克鲁斯卡尔(Kruskal)求最小生成树思想:首先将n个点看着n个独立的集合,将所有边快排(从小到大)。然后,按排好的顺序枚举每一条边,判断这条边连接的两个点是否属于同一个集合。若是,则将这条边加入最小生成树,并将两个点所在的集合合并为一个集合。若否,则跳过。直到找到n-1条边为止。
#include<bits/stdc++.h>
using namespace std;
struct point
{
int x,y,v;
}a[10000];
int cmp(const point &a, const point &b)
{
if(____(1)_____) return 1;
else return 0;
}
int fat[101];
int father(int x)
{
if(fat[x]!=x) return fat[x]=_____(2)______
else return fat[x];
}
void unionn(int x,int y)
{
int fa=father(x);
int fb=father(y);
if(fa!=fb) fat[fa]=fb;
}
int main( )
{
int i,j,n,m,k=0,ans=0,cnt=0;
cin>>n;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
cin>>m;
if(m!=0)
{
k++;
a[k].x=i;
a[k].y=j;
a[k].v=m;
}
}
}
sort(a+1,a+1+k,____(3)____);
for(i=1;i<=n;i++)
{
fat[i]=i;
}
for(i=1;i<=k;i++)
{
if(father(a[i].x)!=____(4)______)
{
ans+=a[i].v;
unionn(a[i].x,a[i].y);
cnt++;
}
if(_____(5)_____) break;
}
cout<<ans;
return 0;
}