給定乙個n個點m條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。
求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。
給定一張邊帶權的無向圖g=(v, e),其中v表示圖中點的集合,e表示圖中邊的集合,n=|v|,m=|e|。
由v中的全部n個頂點和e中n-1條邊構成的無向連通子圖被稱為g的一棵生成樹,其中邊的權值之和最小的生成樹被稱為無向圖g的最小生成樹。
輸入格式
第一行包含兩個整數n和m。
接下來m行,每行包含三個整數u,v,w,表示點u和點v之間存在一條權值為w的邊。
輸出格式
共一行,若存在最小生成樹,則輸出乙個整數,表示最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。
資料範圍
1≤n≤500,
1≤m≤105,
圖中涉及邊的邊權的絕對值均不超過10000。
輸入樣例:
4 51 2 1
1 3 2
1 4 3
2 3 2
3 4 4
輸出樣例:
6適用於:圖中可能存在重邊和自環,邊權可能為負數。求最小生成樹
樸素想法:
每次找到距離集合最短的點,用它更新剩下所有點到集合的距離
做法:
迴圈n次,保證能夠將所有結點收到集合內,一次操作乙個結點
迴圈所有的結點,找到沒在集合內,且距離集合最小的點
用該點更新剩下不在集合內的所有點
重複2 、3步,直到所有點均在集合內
**
/*
s:當前已經在聯通塊中的所有點的集合
1. dist[i] = inf
2. for n 次
t<-s外離s最近的點
利用t更新s外點到s的距離
st[t] = true
n次迭代之後所有點都已加入到s中
聯絡:dijkstra演算法是更新到起始點的距離,prim是更新到集合s的距離
*/#include
#include
using namespace std;
const int n =
510, inf =
0x3f3f3f3f
;int n, m;
int g[n]
[n], dist[n]
;//鄰接矩陣儲存所有邊
//dist儲存其他點到s的距離
bool st[n]
;int prim()
return res;
}int main()
int t =
prim()
;//臨時儲存防止執行兩次函式導致最後僅返回0
if(t == inf)
puts
("impossible");
else cout <
< t <
< endl;
}
堆優化
#include
#include
#include
#include
using namespace std;
const int m=
510,n=
1e5+10;
typedef pair pii;
int n,m;
int cnt,d[m]
;int e[
2*n]
,ne[
2*n]
,h[2
*n],w[
2*n]
,idx;
//必須開兩倍的邊陣列,因為無向圖需要有雙向的邊!!!!!!
bool st[n]
;void add
(int a,int b,int c)
}//如果沒有重邊就加入
e[idx]
=b,w[idx]
=c,ne[idx]
=h[a]
,h[a]
=idx++;}
int prim()
);int res=
0,cnt=0;
while
(!q.
empty()
&& cnt}}}if
(cnt == n)
return res;
return-1
;}int main()
int res=
prim()
;if(res==-1
) cout<
<
"impossible"
;else cout<
return0;
}
858 Prim演算法求最小生成樹
思路 將所有點到集合的距離初始化為正無窮 進行n次迴圈 找到不在集合中且到集合距離最近的點 用找到的點來更新其它點到集合的距離 include include include include using namespace std const int n 510 int n,m int g n n ...
AcWing 858 Prim演算法求最小生成樹
題目描述 給定乙個n個點m條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。給定一張邊帶權的無向圖g v,e 其中v表示圖中點的集合,e表示圖中邊的集合,n v m e 由v中的全部n個頂點和e中n 1條邊構成的無向連通...
Prim演算法求最小生成樹
本文參考 google 資料結構 c語言 prim演算法,求最小生成樹 include include 最小生成樹prim define max 65535 using namespace std struct graph int prim graph g flag 0 1 將0號結點加入集合s i...