第10讲-并查集
课件:(下载)
#include <iostream>
#include <algorithm>
using namespace std;
#define N 101
//边集合,因为是无向图,所以只需要存一半的边
struct edge{
int w;
int v;
int d;
}e[N*N/2];
int father[N];
int n;
int edgeCount;//边的数量
//比较两个边的权值,用于排序
bool Cmp(const edge &v1,const edge &v2)
{
return v1.d<v2.d;
}
//数据初始化和数据输入
void Init()
{
edgeCount=0;
for( int k=1;k<=n;k++ )
{
father[k]=k;
}
int input;
for(int i=1;i<=n;i++)
{
for( int j=1;j<=n;j++ )
{
cin>>input;
if( i<j)
{
e[edgeCount].w = i;
e[edgeCount].v = j;
e[edgeCount].d = input;
edgeCount++;
}
}
}
//所有边按权值大小依次排序,注意第二个参数表示容器的end位置(即最后一个位置的后面一个位置)
sort(e,e+edgeCount,Cmp);
}
int GetFather(int x)
{
if(father[x]==x)
return x;
else
{
father[x] = GetFather(father[x]);//路径压缩
return father[x];
}
}
bool Merge(int x,int y)
{
x=GetFather(x);
y=GetFather(y);
if(x==y)
return false;
else
father[x]=y;
return true;
}
int Kruskal()
{
int sum=0;
for(int i=0;i<edgeCount;i++)
{
if(Merge(e[i].w,e[i].v))
sum+=e[i].d;
}
return sum;
}
int main()
{
while(cin>>n)
{
Init();
cout<<Kruskal()<<endl;
}
return 0;
}