问题 4148 --最小生成树

4148: 最小生成树★★

时间限制: 1 Sec  内存限制: 128 MB
提交: 87  解决: 77
[提交][状态][命题人:]

题目描述

克鲁斯卡尔(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;
}


输入

输出

样例输入
Copy
6
0  1 11 0 0  2
1  0 9  3 0  0
11 9 0  0 8  7
0  3 0  0 10 4
0  0 8  10 0  5
2  0 7  4  5  0
样例输出
Copy
18

提示

来源

[提交][状态]