码迷,mamicode.com
首页 > 其他好文 > 详细

最小生成树

时间:2017-08-19 18:43:54      阅读:123      评论:0      收藏:0      [点我收藏+]

标签:cout   为什么   最优   pen   family   sha   struct   std   blog   

最小生成树有两种算法:

1、prim算法

2、kruskal算法

老师主要给我们讲了第二种算法。最小生成树是包含原图中的所有 n 个结点,并且有保持图连通的最少的边。也就是边权之和最小,并且可以联通所有点的无环图。

1、按边权进行排序

2、找出边权最小的边,如果它们不在一个集合(无环),那就加入最小生成树的集合中。

3、不符合条件就继续找。

4、直到找出n-1条边为止。

  为什么要无环呢,因为形成环以后,即使不用这条边,整个图也是能够联通的,所以说这条边是不必要的。排在前面把整个图联通起来的边必定是最短的,是最优的选择。

  但是要注意,在合并最小生成树时,是把它们的祖先合并,并不是两个数合并。这可是个大错误!!!

参考代码——

struct ee{
	int to;
	int from;
	int l;
}f[10005];
bool cmp(ee x,ee y)
{
	return x.l<y.l;
}//排序
int finda(int x)
{
	if(father[x]==x) return x;
	return father[x]=finda(father[x]);
}
int main()
{
	freopen("1592.in","r",stdin);
	freopen("1592.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++) father[i]=i;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a;
			if(a==0) continue;
			else
			{
				e++;
				f[e].from=i;
				f[e].to=j;
				f[e].l=a;
			}
		}
	}
	sort(f+1,f+1+e,cmp);
	int ans=0;
	for(int i=1;i<=e;i++)
	{
		if(finda(f[i].from)!=finda(f[i].to))//判断是否在同一个并查集里
		{
			ans+=f[i].l;
			father[finda(f[i].from)]=finda(f[i].to);//合并祖先
		}
	}
	cout<<ans<<endl;
	return 0;
}

  

最小生成树

标签:cout   为什么   最优   pen   family   sha   struct   std   blog   

原文地址:http://www.cnblogs.com/yiyiyizqy/p/7397044.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!