題目描述:
給定乙個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≤10^5,
圖中涉及邊的邊權的絕對值均不超過10000。
輸入樣例:
4 5
1 2 1
1 3 2
1 4 3
2 3 2
3 4 4
輸出樣例:
6
分析:
prim演算法與dijkstra演算法十分類似。都是基於點集的,每次找離點集最近的點,連上點集到該點的邊。不同的是dijkstra演算法用鬆弛操作來更新最短路徑,而prim演算法只需要每次選離點集最近的點,將邊長加入最小生成樹的權重中即可。如何尋找離點集最近的點,只需修改下dijkstra演算法d陣列的含義為某點向點集中連線的邊的最小邊的長度即可。每次加入某條邊進生成樹,即用選中的邊的頂點更新其他連線邊的最短邊的長度。鑑於演算法較為簡單,具體過程見**。
#include #include #include using namespace std;
const int maxn = 505,inf = 0x3f3f3f3f;
int n,m,g[maxn][maxn],d[maxn];
bool vis[maxn];
int prim()
return res;
}int main()
int res = prim();
if(res == -1) puts("impossible");
else printf("%d\n",res);
return 0;
}
858 Prim演算法求最小生成樹
給定乙個n個點m條邊的無向圖,圖中可能存在重邊和自環,邊權可能為負數。求最小生成樹的樹邊權重之和,如果最小生成樹不存在則輸出impossible。給定一張邊帶權的無向圖g v,e 其中v表示圖中點的集合,e表示圖中邊的集合,n v m e 由v中的全部n個頂點和e中n 1條邊構成的無向連通子圖被稱為...
858 Prim演算法求最小生成樹
思路 將所有點到集合的距離初始化為正無窮 進行n次迴圈 找到不在集合中且到集合距離最近的點 用找到的點來更新其它點到集合的距離 include include include include using namespace std const int n 510 int n,m int g n n ...
Prim演算法 Kruskal演算法
一 prim演算法 1 要求 1 生成一顆連通的樹 2 生成樹 包含全部頂點,v 1條邊,沒有迴路,並且新增一條邊會變成有迴路 3 權重和最小 2 過程模擬 最重要 貪心的思想,每一步都要選擇權值最小的,這棵樹所有跟頂點相連的邊中最小的。從根節點開始,讓樹慢慢的長大。過程 從v1開始 跟v1有聯絡的...