1. 程式人生 > >最小生成樹kruskal模板

最小生成樹kruskal模板

sizeof algorithm sta () 一個 queue ems bool class

算法思路:每次選取權值最小的邊,判斷這兩個點是否在同一個集合內,如果在則跳過,如果不在則加上這條邊的權值

可以使用並查集儲存結點,可以快速判斷結點是否在同一集合內。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<vector>
 6 #include<stack>
 7 #include<cstdio>
 8 #include<map>
 9 #include<set
> 10 #include<string> 11 #include<queue> 12 using namespace std; 13 #define inf 0x3f3f3f3f 14 typedef long long ll; 15 map<ll,ll> mp; 16 const int maxn=1e5+50;//邊數 17 struct edg{ 18 int u; 19 int v; 20 int w; 21 bool operator < (const edg e) 22 const{ 23 return
w<e.w; 24 } 25 }st[maxn]; 26 int fa[maxn];//並查集 27 int cnt;//邊數 28 void addedg(int u,int v,int w){ 29 st[cnt].u=u; 30 st[cnt].v=v; 31 st[cnt++].w=w; 32 } 33 int find(int i){ 34 if(fa[i]==-1) 35 return i; 36 else 37 return find(fa[i]); 38 } 39 int kruskal(int n){ 40 sort(st,st+cnt);
41 memset(fa,-1,sizeof(fa)); 42 int u,v; 43 int ans=0,count=0; 44 int f1,f2; 45 for(int i=0;i<cnt;i++){ 46 u=st[i].u; 47 v=st[i].v; 48 f1=find(u); 49 f2=find(v); 50 if(f1!=f2){ 51 fa[f1]=f2; 52 ans+=st[i].w; 53 count++; 54 } 55 } 56 if(count==n-1){ 57 return ans; 58 } 59 else{ 60 return -1; 61 } 62 } 63 int main(){ 64 int n,m; 65 int u,v,w; 66 int ans; 67 cin>>n>>m;//點,邊的數量 68 cnt=0; 69 for(int i=0;i<m;i++){ 70 cin>>u>>v>>w; 71 addedg(u,v,w); 72 } 73 ans=kruskal(n); 74 if(ans==-1){ 75 cout<<"該圖沒有連通"<<endl; 76 } 77 else{ 78 cout<<ans<<endl; 79 } 80 return 0; 81 }

最小生成樹kruskal模板