4-6 最小生成树Prim,Kruskal(贪心)
创始人
2024-01-28 17:57:50

4.6最小生成树 Prim,Kruskal(贪心)

一、问题描述

设G =(V,E)是无向连通带权图,即一个网络。E中每条边(u,v)的权为 c[u][v]。
如果G的子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树上各边权的总和称为该生成树的耗费。
在G的所有生成树中,耗费最小的生成树称为G的最小生成树(Minimum Spanning Tree ),简称MST。

二、构造最小生成树的有效算法:Prim算法和Kruskal算法,

两者贪心选择的方式不同,但都利用了最小生成树性质(贪心策略)∶设G=(V,E)是连通带权图,U是V的真子集。如果(u,v)eE,且ueU , veV-U且在所有这样的边中,(u,v)的权c[u][v]最小,那么一定存在G的一棵最小生成树,它以(u,v)为其中一条边。这性质称为MST(最小生成树)性质。

1.Prim算法(选顶点加入集合S)

- 每次选取能到达的最小的边

设G=(V,E)是连通带权图,V={1,2,.n}。构造G的最小生成树的Prim算法的基本思想是∶
(1)首先置S={1},
(2)然后,只要S是V的真子集,就作如下的贪心选择:选取满足条件i∈S, j∈V-S,且c[i][i]是最小的边,将顶点j添加到S中。
(3)这个过程一直进行到S=V时为止。
在这个过程中选取到的所有边恰好构成G的一棵最小生成树。

2.Kruskal算法(选择连接属于两个不同连通分支的最小边)

- 每次选取最短的且不构成回路的边

(1)首先将G的n个顶点看成n个孤立的连通分支。
(2)所有的边按权从小到大排序。
(3)顺序检查每条边,如果一条边的端点v和w分别是当前2个不同的连通分支T1和T2,用边(v,w)将T1和T2连接成一个连通分支,否则放弃这条边。
(4)该过程一直到只剩一个连通分支时为止(选择了n-1条边为止)。

三、代码

1.Prim算法(选顶点加入集合S)

- 每次选取能到达的最小的边

//最小生成树Prim算法 
/*每次将能到达的最短的边加进去 
closest[j]是j在S中的邻接顶点,
先找出V-S中使c[j][closest[j]](即lowcost[j]) 值最小的顶点j,
然后根据数组closest选取边(j,closest[j]),然后将j添加到S中,
最后对closest和lowcost做修改 
*/
#include
#include
#define INF 0x3f3f3f
using namespace std;
int n,m;//n个顶点,m条边
int c[100][100];
int s[1000];//s[i]=1表示顶点i被挑出来了,在生成树里了 
int closest[1000];//closest[j]是j在S中的邻接顶点
int lowcost[1000];//lowcost[j]就是c[j][closest[j]] 
void Prim(){for(int i=2;i<=n;i++){//初始化 lowcost[i]=c[1][i];closest[i]=1;s[i]=0; }s[1]=1; for(int i=1;iint t=INF;int j=1;//从第一个结点开始 for(int k=2;k<=n;k++){if(lowcost[k]t = lowcost[k]; j=k;}}cout<<"("<if(c[j][k]lowcost[k] = c[j][k];closest[k]=j;		}}}
}
int main(){cin>>n>>m;int i,j;int x,y,z;for(i=0;i<=n;i++) //初始化 for(j=0;j<=n;j++)c[i][j]=INF;for(i=0;icin>>x>>y>>z;c[x][y]=z;c[y][x]=z;} cout<<"Prim:依次加入的顺序为:\n";	Prim();return 0;
}

2.Kruskal算法(选择连接属于两个不同连通分支的最小边)

- 每次选取最短的且不构成回路的边

//最小生成树Kruskal
//每次选图中权值最小的边 
#include
#include
#include
using namespace std;
int n,m;//n个顶点,m条边
int s[1000];//并查集s[i]=1表示顶点i的父结点是1,即i与1在一个集合
struct edge{int u,v,w;//顶点u到顶点v的权重是w(无向图) 
}g[1000];
bool comp(edge a,edge b){return a.w < b.w;
}
int Init(){for(int i=0;is[i]=i;//初始化,现在各自为王,自己就是一个集合}
} 
int Find(int x){//查询根结点if(s[x]==x)return x;else{s[x]=Find(s[x]);  //顺便把双亲结点也设置为根结点,路径压缩return s[x];}	
}
void Merge(int x,int y){//合并,把 y 合并到 x 中去,就是把y的双亲结点设为xs[Find(y)] = Find(x);
}
void Kruskal(){int x,y;for(int i=0;ix = g[i].u;y = g[i].v;if(Find(x) != Find(y)){cout<<"("<cin>>n>>m;int i;int x,y,z;for(i=0;icin>>x>>y>>z;g[i].u=x;g[i].v=y;g[i].w=z;} sort(g,g+m,comp);Init();cout<<"依次加入的顺序为:\n";Kruskal();return 0;
}

四、运行截图

测试用例

/*
6  10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
*/ 

在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
上海有几个区 最新上海16区划... 你平常会使用地图吗?一幅标准的地图可以帮助我们解决很多问题。自然资源部最新公布了长三角标准地图,上海...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
男生摸女生胸 同桌把我带到卧室... 所谓“酒色财气”,酒与色往往是连在一起的,澳洲有个医学生,就因为两次酒后猥亵自己的同学,几乎葬送了自...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...