【Kruskal最小生成树】算法模板+例题

Kruskal最小生成树

生成树 
已知连通图G ,图上有N个顶点。生成树是指图G的一个极小(边最少)连通子图,生成树上有n个顶点、n-1条边,且任意两点之间都是连通的。 
最小生成树 
已知带权连通图G,图中有n个顶点,每条边都有权值。我们要从图中抽出一棵生成树,使得树上所有边权之和最小,这棵生成树就叫做 最小生成树。 
常见变形应用: 
1.要求找最大边权最小的的生成树(多读几遍):直接找最小生成树即可; 
2.次小生成树:求最小生成树,每次删除最小生成树上一条边,求最小生成树,取最小值 
3.边权极差最小的生成树:枚举每一个边,令他的边权最小,求最小生成树(所以边权比他小的边不参与),求与加入该生成树中的最大边权的极差即可。 

Kruskal算法流程: 
首先定义带权无向图G的边集合为E,接着我们再定义最小生成树的边集为T,初始集合T=0 。接着执行以下操作: 
边按权值从小到大排序,然后依次去放置,注意过程中要用并查集判断是否产生回路。最终添加了n-1条边即得到最小生成树。


#include
#include
using namespace std;

const int MAXN=10000;
const int MAXM=10000;
struct edge
{
	int u,v,w;
}e[MAXM];

bool cmp(edge a,edge b)  //重要! 
{
	if(a.w>n>>m;
	for(int i=1;i<=m;i++)
		scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
	sort(e+1,e+m+1,cmp);   //把边按边权排序! 
	for(int i=1;i<=n;i++)
		father[i]=i;
	int res=0; //记录添加到最小生成树中的边数(最终=n-1即可 !!! 
	int ans=0; //记录边权值和
	for(int i=1;i<=m && res


例题1:布设光纤

【Kruskal最小生成树】算法模板+例题_第1张图片

思路:

就是克鲁斯卡尔求最小生成树的裸题,题目的那个要求就是最小生成树的定义呀。

和模板一样,唯一区别在于输入边权值的方式不同。

#include
#include
using namespace std;

const int MAXN=10000;
const int MAXM=10000;
struct edge
{
	int u,v,w;
}e[MAXM];

bool cmp(edge a,edge b)  //重要! 
{
	if(a.w>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++) //对称的 
		{
			int w;
			cin>>w;
			if(i!=j)
			{
				insert2(i,j,w);				
			}
		}
	}
	cnt--;
	sort(e+1,e+cnt+1,cmp);   //把边按边权排序! 
	for(int i=1;i<=n;i++)
		father[i]=i;
	int res=0; //记录添加到最小生成树中的边数(最终=n-1即可 !!! 
	int ans=0; //记录边权值和
	for(int i=1;i<=cnt && res


你可能感兴趣的:(蓝桥杯)