最小生成樹(Kruskal)
阿新 • • 發佈:2018-12-11
#include<iostream> #include<cstdio> #include<vector> #include<algorithm> using namespace std; int flag = 0; struct Edge{ int u,v,w; }edge[200005]; struct Node{ int to,val; }; vector<Node> node[200005]; int fa[5005],n,m,ans,eu,ev,cnt; inline bool cmp(Edge a,Edge b) { return a.w<b.w; } //快排的依據 inline int find(int x){ if (x!=fa[x]) fa[x]=find(fa[x]); return fa[x]; } //並查集迴圈實現模板,及路徑壓縮, inline void kruskal() { sort(edge,edge+m,cmp); //將邊的權值排序 for(int i=0;i<m;i++) { eu=find(edge[i].u), ev=find(edge[i].v); if(eu==ev) { continue; } //建立一張新圖表示最小生成樹 node[edge[i].u].push_back(Node{edge[i].v,edge[i].w}); //node[edge[i].v].push_back(Node{edge[i].u,edge[i].w});<—若是無向圖加上這行 //若出現環,則continue ans+=edge[i].w; //將此邊權計入答案 fa[ev]=eu; if(++cnt==n-1) { flag = 1; break; } //迴圈結束條件,及邊數為點數減一時 } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { fa[i]=i; } //初始化並查集 for(int i=0;i<m;i++) { scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); } kruskal(); if(flag)printf("%d\n",ans); else{ printf("-1\n");//不連通 } return 0; }