【ACM算法】-- 图论篇 - 最小生成树(MST)

青春壹個敷衍的年華 提交于 2020-03-03 00:20:32

第一题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这里讨论最小生成树问题,最小生成树是原图的一个子图,其中包含所有节点,仅含有部分边,使得这个子图为连通图,且不含有环路,并且边上的权值和最小,则称为最小生成树。

思路: 这道题用克鲁斯卡尔的方法来求最小生成树:
在这里插入图片描述
如上图:我们需要两种数据结构,一个是用来确定两个点是否属于一个集合,另一个是我们要将边的权值进行排序,需要一个struct来存储边,并且用到了重载小于号,使用sort快排。

代码如下:

#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 101
int Tree[N];
int findRoot(int x){
	if(Tree[x]==-1)return x;
	else{
		int tmp=findRoot(Tree[x]);
		Tree[x]=tmp;
		return tmp;
	}
}
struct Edge{
	int a,b;
	int cost;
	bool operator<(const Edge &A)const{
		return cost<A.cost;
	}
}edge[6000];
int main(){
	int n;
	freopen("in.txt","r",stdin);
	while(scanf("%d",&n)!=EOF&&n!=0){
		for(int i=1;i<=n*(n-1)/2;i++){
			scanf("%d%d%d",&edge[i].a,&edge[i].b,&edge[i].cost);
		}
		sort(edge+1,edge+1+n*(n-1)/2);
		for(int i=1;i<=n;i++){
			Tree[i]=-1;
		}
		int ans=0;
		for(int i=1;i<=n*(n-1)/2;i++){
			int a=findRoot(edge[i].a);
			int b=findRoot(edge[i].b);
			if(a!=b){
				Tree[a]=b;
				ans+=edge[i].cost;
			}
		}//注意,最小生成树,要求全图连通,因为题目中给出,是个完全图。所以不用考察连通分量的问题
		printf("%d\n",ans);
	}
	return 0;
}

第二题:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!