最小生成树

Posted yiyiyizqy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树相关的知识,希望对你有一定的参考价值。

最小生成树有两种算法:

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;
}

  

以上是关于最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树matlab代码Kruskal算法,用于二维网络生成

c语言最小生成树

最小生成树及Prim算法及Kruskal算法的代码实现

数据结构 图连通与最小生成树

次最小生成树 模版

图的最小生成树算法(图解+代码)| 学不会来看我系列