Kruskal算法的连接两棵树的方法有很多,按照需要连就可以了。
#include <iostream>
#include <algorithm>
#define N 502
#define infinite 65540
using namespace std;
struct kruskal
{
int from;
int to;
int value;
};
int village;
int father[N],son[N];
kruskal edgeValue[N*N/2];
int unionSearch(int x)
{
return x==father[x]?x:unionSearch(father[x]);
}
bool joint(int x,int y)
{
int rootx,rooty;
rootx=unionSearch(x);
rooty=unionSearch(y);
if(rootx==rooty)
return false;
else
{
if(son[rootx]>=son[rooty])
{
//这里的是father[rooty]而不是father[y],那样子的话并没有链接整棵树,
//只是链接了这个点,链接的方式有很多,按照需要,也可以一直将树x链接在y上
//就是在这里wa了很多次。。。。
father[rooty]=rootx;
son[rootx]+=son[rooty];
}
else
{
father[rootx]=rooty;
son[rooty]+=son[rootx];
}
return true;
}
}
int cmp(kruskal &a,kruskal &b)
{
return a.value<b.value;
}
int main()
{
int Cases;
//freopen("in.txt","r",stdin);
scanf("%d",&Cases);
while (Cases--)
{
int j,k,i=1,sum=0,count=0,minLength=0,temp;
int flag=0;
scanf("%d",&village);
for (j=1;j<=village;j++)
{
for (k=1;k<=village;k++)
{
scanf("%d",&temp);
if(temp!=0&&j>=k)
{
edgeValue[i].from=j;
edgeValue[i].to=k;
edgeValue[i++].value=temp;
}
}
}
for (j=1;j<=village;j++)
{
father[j]=j;
son[j]=1;
}
sort(edgeValue+1,edgeValue+i+1,cmp);//注意比较的范围
for (j=1;j<i;j++)
{
if(joint(edgeValue[j].from,edgeValue[j].to))
{
count++;
if (edgeValue[j].value>minLength)
minLength=edgeValue[j].value;
}
if (count==village-1)
{
flag=1;
break;
}
}
if(flag)
cout << minLength << endl;
}
}