克鲁斯卡尔算法(模板)
/* INPUT 6 10 1 2 6 1 3 1 1 4 5 2 3 5 2 5 3 3 4 5 3 5 6 3 6 4 4 6 2 5 6 6 OUTPUT 15 */ #include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; const int N=1e5; struct node { int u,v,w; bool operator<(const node &C)const { return w<C.w;//表示以w从小到大排序 } }t[N]; int n,m; int p[1001]; int cha(int x) { //return x==p[x]?p[x]:cha(p[x]); if(x!=p[x]) { p[x]=cha(p[x]);//一直找到祖先 } return p[x]; } int cl() { int sum=0,top=0; for(int i=0;i<m;i++)//从第一条边开始遍历 { int x=t[i].u; int y=t[i].v; x=cha(x); y=cha(y); if(x!=y)//假如不是同一祖宗,就连,如果是同一个祖宗也连的话,就会形成回路 { p[x]=y;//则将其中一个点作为另一个点的祖宗,就把点与点连起来了 sum+=t[i].w; top++;//累计连接线的条数 } if(top==n-1) return sum;//要使n个点全部连通,至少需要n-1条边 } return -1;//无法连通 } int main() { while(scanf("%d%d",&n,&m)!=EOF)//n个点,m条边 { for(int i=1;i<=n;i++) p[i]=i;//并查集 开始全部初始化为本身 for(int i=0;i<m;i++) { scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].w//分别代表起点,终点,权值 } sort (t,t+m);//保证后面取数都是目前最小的 printf("%d\n",cl()); } return 0; }