kruskal
基本思想:
算法的第一步是给所有的边按照从小到大的顺序排序。这一步可以直接使用库函数qsort或者sort。接下来从小到大依次
考察每一条边(u,v)。
具体实现过程如下:
<1> 设一个有n个顶点的连通图为G(V,E),最初先构造一个只有n个顶点,没有边的非连通图T={V,空}。
<2> 在G中选择一条具有最小权植的边时,若该边的两个顶点在T中连接不会形成环(环可以用并查集判断(是否为同一个祖
先)),则将此边加入到T中;否则,将此边舍去(此后永不选用这条边),重新选择一条权植最小的边。(可以先排序)
<3> 如此重复下去,直到所有顶点在连通为止。
#include<bits/stdc++.h>
using namespace std;
int v[10000010];
struct node
{
long long int u,v,w;
} a[10000010];
long long int cmp(node a,node b)
{
return a.w<b.w;
}
long long int dd(int x)
{
return v[x]==x?v[x]:v[x]=dd(v[x]);
}
long long int f(int a,int b)
{
long long int x=dd(a),y=dd(b);
if(x!=y)
{
v[y]=x;
return 1;
}
else return 0;
}
int main()
{
long long int i,n,m,s=0,temp=0;
scanf("%lld%lld",&n,&m);
for(i=0; i<=n+2; i++) v[i]=i;
for(i=1; i<=m; i++)
{
scanf("%lld%lld%lld",&a[i].u,&a[i].v,&a[i].w);
}
sort(a+1,a+1+m,cmp);
for(i=1; i<=m; i++)
{
if(temp==n-1) break;
if(f(a[i].u,a[i].v))
{
temp++;
s+=a[i].w;
}
}
printf("%lld",s);
return 0;
}