最小生成樹---Kruskal演算法---挑戰程式設計競賽讀書筆記
阿新 • • 發佈:2019-01-09
測試資料也一樣。
這個演算法用到並查集來高效的判斷頂點u,v是否屬於同一個聯通分量。
程式碼:
#include <iostream> #include <cstring> #include <cstdlib> #include <algorithm> #include <fstream> using namespace std; const int max_e=100; const int max_v=100; const int inf=99999; struct edge{ int from,to,weight; } ; edge es[max_e]; bool cmp(const edge &a,const edge &b){ return a.weight<b.weight; } int V,E; //V vertexs,{1,2,3...n}, E edges. // union_set int par[max_v],rank[max_v]; void inin_union_set(int v) { for(int i=1;i<=v;i++){ par[i]=i; rank[i]=0; } } int find(int x){ if(par[x]==x)return x; else return par[x]=find(par[x]); } void union_set(int x,int y){ x=find(x); y=find(y); if(x==y)return ; if(rank[x]<rank[y]){ par[x]=y; } else { par[y]=x; if(rank[x]==rank[y]) rank[x]++; } } int Kruskal() { sort(es,es+E,cmp); inin_union_set(V); int res=0; for(int i=0;i<E;i++) { edge e=es[i]; if( find(e.from)!=find(e.to) ) { union_set(e.from,e.to); res+=e.weight; } } return res; } int main() { ifstream fin; fin.open("input.txt"); while(fin>>V>>E) { for(int i=0;i<E;i++){ fin>>es[i].from>>es[i].to>>es[i].weight; } cout<<Kruskal()<<endl; } return 0; }