这是最小生成树当中的Kruskal算法的模板题。
Kruskal算法是基于贪心的思想,利用并查集求出连通图的最小生成树。关于其详解可参考博客:
https://blog.youkuaiyun.com/luoshixian099/article/details/51908175
https://blog.youkuaiyun.com/stary_yan/article/details/51427864#算法描述-1
很神奇的就是Kruskal居然不用建一个图的,只需记录下边的信息就好了。
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e4+5;
struct edge
{
int f,t;
int wei;
}E[maxn];
int fa[55],ans;
bool cmp(edge x,edge y)
{
return x.wei<y.wei;
}
void init()
{
for(int i=0;i<55;i++)
fa[i]=i;
}
int find(int x)
{
if(x==fa[x])
return x;
return find(fa[x]);
}
bool unite(int x,int y,int wei)
{
x=find(x);
y=find(y);
if(x!=y)
{
fa[x]=y;
ans+=wei;
return 1;
}
else return 0;
}
int main()
{
int p,r;
while(~scanf("%d",&p)&&p)
{
scanf("%d",&r);
init();
for(int i=1;i<=r;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(a>b) swap(a,b);
E[i].f=a;
E[i].t=b;
E[i].wei=c;
}
sort(E+1,E+r+1,cmp);
int cnt=p-1,temp=1;
ans=0;
while(cnt)
{
if(unite(E[temp].f,E[temp].t,E[temp].wei))
cnt--;
temp++;
}
printf("%d\n",ans);
}
return 0;
}