博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最小生成树-Prim算法和Kruskal算法
阅读量:5078 次
发布时间:2019-06-12

本文共 3625 字,大约阅读时间需要 12 分钟。

 

  在解决这个问题之前,我觉得有必要先解释一下什么叫做生成树,什么叫做最小生成树。给定一个图,如果它的某个子图中任意两个顶点都互相联通并且是一棵树,那么这棵树就叫做生成树。如果边上有权值,那么使得权值和最小的树叫做最小生成树。

  安全边:当一条边(u,v)加入T时,必须保证T∪{(u,v)}仍是MST的子集,我们将这样的边称为T的安全边。

  求MST(minimum spanning tree)的一般算法可描述为:针对图G,从空树T开始,往集合T中逐条选择并加入n-1条安全边(u,v),最终生成一棵含n-1条边的MST。求解最小生成树的方法主要有以下两种:

  一、Prim算法:

  贪心的将MST和其他顶点相连的最小权值的边加入MST,重复操作,直到MST中有n条边。如果我们要高效地使用Prim算法,我们可以使用最小堆。下面看一下这个算法的图解:

 

二、kruskal算法

kuskal的贪心策略更加容易理解:每次都选取最小权值的安全边,然后加入MST,直到MST中有n-1条边。当然,高效的查找需要用到并查集,比如下面的第二道例题,而且也需要使用最小堆。下面看kruskal的图解:

 

 

三、经典题目:

1.HDU 1233

还是畅通工程

描述

某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。 

Input

测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。 

当N为0时,输入结束,该用例不被处理。

 

Output

对每个测试用例,在1行里输出最小的公路总长度。 

Sample Input

31 2 11 3 22 3 441 2 11 3 41 4 12 3 32 4 23 4 50

Sample Output

35
#include
#include
using namespace std;const int maxn=105;const int INF=0x3fffffff;int graph[maxn][maxn];int n;int Prim(){ int min_cost[maxn]; bool used[maxn]; for(int i=0;i
View Code

 

2.Constructing Roads  (HDU 1102)

There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected. 
We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum. 

InputThe first line is an integer N (3 <= N <= 100), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 1000]) between village i and village j. 

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built. 
OutputYou should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum. 
Sample Input

30 990 692990 0 179692 179 011 2

Sample Output

179
#include
#include
using namespace std;struct Node{ int x,y,cost; Node() {} Node(int xx,int yy,int cc):x(xx),y(yy),cost(cc){} friend bool operator<(Node a,Node b);};const int maxn=10000;int fa[maxn];void init(){ for(int i=0;i
s; while(~scanf("%d",&n)) { init(); s.clear(); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { int num; scanf("%d",&num); if(i!=j) { s.insert(Node(i,j,num)); } } } int q,ans=0,counter=0; //counter表示已经连接的边数 scanf("%d",&q); while(q--) { int xx,yy; scanf("%d%d",&xx,&yy); if(GetRoot(xx)!=GetRoot(yy)) counter++; Unite(xx,yy); } multiset
::iterator it=s.begin(); while(counter
cost; counter++; } it++; } printf("%d\n",ans); }}bool operator<(Node a,Node b){ return a.cost
View Code

 

转载于:https://www.cnblogs.com/Lewin671/p/8976910.html

你可能感兴趣的文章
跨平台开发 -- C# 使用 C/C++ 生成的动态链接库
查看>>
C# BS消息推送 SignalR介绍(一)
查看>>
WPF星空效果
查看>>
WPF Layout 系统概述——Arrange
查看>>
PIGOSS
查看>>
软件目录结构规范
查看>>
解决 No Entity Framework provider found for the ADO.NET provider
查看>>
设置虚拟机虚拟机中fedora上网配置-bridge连接方式(图解)
查看>>
ES6内置方法find 和 filter的区别在哪
查看>>
Android实现 ScrollView + ListView无滚动条滚动
查看>>
java学习笔记之String类
查看>>
UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)
查看>>
硬件笔记之Thinkpad T470P更换2K屏幕
查看>>
蓝桥杯-分小组-java
查看>>
Android Toast
查看>>
iOS开发UI篇—Quartz2D使用(绘制基本图形)
查看>>
docker固定IP地址重启不变
查看>>
桌面图标修复||桌面图标不正常
查看>>
JavaScript基础(四)关于对象及JSON
查看>>
JAVA面试常见问题之Redis篇
查看>>