借鉴,觉得写的最好的最小生成树的prim算法和kruskal算法
kruskal算法利用并查集来解决问题,更加方便使用。
VJ最小生成树,畅通工程,G
/*
最小生成树测试样例
10 6
1 2 4
1 5 1
1 6 2
2 3 6
2 6 3
3 4 6
3 6 5
4 5 4
4 6 5
5 6 3
15
*/
#include<bits/stdc++.h>
using namespace std;
int pre[101],n,m,cct=0,sum=0,dif=1;//dif完全可以写成0,因为这是修改过来的代码
struct edges{
int a,b;int c;
}edge[101];
bool cmp(struct edges a,struct edges b)
{
return a.c<b.c;
}
int findroot(int t)
{
if(pre[t]==t) return t;
else return findroot(pre[t]);
}
int main()
{
while(1)
{
sum=0,dif=1;
scanf("%d%d",&m,&n);
if(m==0||n==0) return 0;
for(int i=1;i<=100;i++) pre[i]=i;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].c);
}
sort(edge+1,edge+1+m,cmp);
for(int i=1;i<=m;i++)
{
int l=findroot(edge[i].a);
int r=findroot(edge[i].b);
if(l!=r)
{
sum+=edge[i].c;
pre[r]=l;
}
}
for(int i=1;i<=n;i++)
{
if(pre[i]==i) dif++;
//只允许有一个数与pre数组查询值相同。这是根
}
/*上面的循环用来巡查是否有没有纳入最小生成树的结点(因为形成生成树,所有结点必定全部包含在里面),也可以对所有结点依次findroot()寻根统计。
*/
if(dif==2) printf("%d\n",sum);
else printf("?\n");
}
}