C++数据结构之最小生成树
最小生成树是图的一部分,一般求最小生成树用Prim算法和Kruskal算法。
对于Prim算法,思想是:在访问过的顶点和未访问的顶点之间选择权值最小的边。Prim算法是基于顶点的操作,适合于顶点较少,边较多的图。
对于Kruskal算法,思想是:直接从图中选择权值最小的边,并且已选择的边不能构成连通图。Kruskal算法是基于边的操作,适合于边较少,顶点较多的图。
Prim算法,在此我用了关联容器pair作为边的存储结构:
//普里姆算法
int Prim(const int G[][VNUM], vector<pair<int, int> > &edge)
{
int w = 0; //权重
vector<int> visited(VNUM, 0); //已访问节点集合
//初始化
visited[0] = 1; //0号节点已访问
//循环VNUM-1次
int u, v;
for(int number = 1; number < VNUM; ++number)
{
int min = M;
for(int i = 0; i != VNUM; ++i) //一次循环有一个节点入栈
{
if(visited[i] == 1)
{
for(int j = 1; j != VNUM; ++j) //判断边(i, j)的权值,i为已访问节点,j为未访问节点
{ if(visited[j] == 0 && G[i][j] < min)
{
min = G[i][j];
v = i;
u = j;
}
}
}
}
w += G[v][u];
visited[u] = 1;
edge[number-1].first = v;
edge[number-1].second = u;
}
return w;
}
克鲁斯卡尔算法的最小生成树结构用并查集表示,并查集在次主要用来判断已选择的边是否构成连通图,如果对应顶点x,y的FindRoot()操作返回的结果相同,即他们的根相同,则能够成连通图,说明选择的边不满足条件。
//并查集结构
class DisjointSet{
public:
vector<int> father;
DisjointSet(int VNUM){
father.resize(VNUM, -1);
}
int FindRoot(int x)
{
while(father[x] >= 0)
x = father[x];
return x;
}
void Union(int x, int y)
{
father[FindRoot(x)] = FindRoot(y);
}
};
//Kruskal
int Kruskal(const int G[][VNUM], vector<pair<int, int> > &edge)
{
int min = M;
int w = 0;
int v, u;
DisjointSet V(VNUM);
for(int num = 0; num != VNUM-1; ++num)
{
min = M;
for(int i = 0; i != VNUM; ++i)
{
for(int j = 0; j != VNUM; ++j)
{
if(G[i][j] < min && V.FindRoot(i) != V.FindRoot(j))
{
min = G[i][j];
v = i;
u = j;
}
}
}
w += G[u][v];
V.Union(u, v);
edge[num].first = v;
edge[num].second = u;
}
return w;
}
下面是主程序:
/*************************
Date : 2013-9-20
Author : DVD0423
Function: 无向图的最小生成树
******************&******/
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
const int M = 10; //两节点无边权值用M表示
const int VNUM = 6; int Prim(const int G[][VNUM], vector<pair<int, int> > &edge);
int Kruskal(const int G[][VNUM], vector<pair<int, int> > &edge); int main()
{
const int G[VNUM][VNUM] = {
M, 9, 1, M, 7, 2,
9, M, 5, 1, M, 6,
1, 5, M, 4, 2, 6,
M, 1, 4, M, 9, 3,
7, M, 2, 9, M, M,
2, 6, 6, 3, M, M
};
vector<pair<int, int> > edge(VNUM-1); //Prim
cout<<"普里姆算法:"<<endl;
cout<<"总路径长度:"<<Prim(G, edge)<<endl;
for(int i = 0; i != VNUM-1; ++i)
cout<<"("<<edge[i].first<<", "<<edge[i].second<<")"<<endl; //Kruskal
cout<<"克鲁斯卡尔算法:"<<endl;
cout<<"总路径长度:"<<Kruskal(G, edge)<<endl;
for(int i = 0; i != VNUM-1; ++i)
cout<<"("<<edge[i].first<<", "<<edge[i].second<<")"<<endl; return 0;
}
输出结果如下:
C++数据结构之最小生成树的更多相关文章
- 【数据结构】 最小生成树(四)——利用kruskal算法搞定例题×3+变形+一道大水题
在这一专辑(最小生成树)中的上一期讲到了prim算法,但是prim算法比较难懂,为了避免看不懂,就先用kruskal算法写题吧,下面将会将三道例题,加一道变形,以及一道大水题,水到不用高级数据结构,建 ...
- 【数据结构】 最小生成树(三)——prim算法
上一期介绍到了kruskal算法,这个算法诞生于1956年,重难点就是如何判断是否形成回路,此处要用到并查集,不会用当然会觉得难,今天介绍的prim算法在kruskal算法之后一年(即1957年)诞生 ...
- 【数据结构】 最小生成树(二)——kruskal算法
上一期说完了什么是最小生成树,这一期咱们来介绍求最小生成树的算法:kruskal算法,适用于稀疏图,也就是同样个数的节点,边越少就越快,到了数据结构与算法这个阶段了,做题靠的就是速度快,时间复杂度小. ...
- 数据结构:最小生成树--Prim算法
最小生成树:Prim算法 最小生成树 给定一无向带权图.顶点数是n,要使图连通仅仅需n-1条边.若这n-1条边的权值和最小,则称有这n个顶点和n-1条边构成了图的最小生成树(minimum-cost ...
- 数据结构:最小生成树--Kruskal算法
Kruskal算法 Kruskal算法 求解最小生成树的还有一种常见算法是Kruskal算法.它比Prim算法更直观.从直观上看,Kruskal算法的做法是:每次都从剩余边中选取权值最小的,当然,这条 ...
- 数据结构--画画--最小生成树(Prim算法)
通信网络的最小生成树配置,它是使右侧的生成树值并最小化.经常使用Prim和Kruskal算法.看Prim算法:以防万一N={V,{E}}它是在通信网络,TE它是N设置边的最小生成树.从算法U={u0} ...
- 数据结构之最小生成树Prim算法
普里姆算法介绍 普里姆(Prim)算法,是用来求加权连通图的最小生成树算法 基本思想:对于图G而言,V是所有顶点的集合:现在,设置两个新的集合U和T,其中U用于存放G的最小生成树中的顶点,T存放G的最 ...
- 数据结构之最小生成树Kruskal算法
1. 克鲁斯卡算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路. 具体做法:首先构造一个 ...
- 【数据结构】最小生成树之prim算法和kruskal算法
在日常生活中解决问题经常需要考虑最优的问题,而最小生成树就是其中的一种.看了很多博客,先总结如下,只需要您20分钟的时间,就能完全理解. 比如:有四个村庄要修四条路,让村子能两两联系起来,这时就有最优 ...
随机推荐
- 用来控制 XML 序列化的属性
通过将下表中的属性应用于类和类成员,可以控制 XmlSerializer 序列化或反序列化该类的实例的方式.若要了解这些属性如何控制 XML 序列化,请参见使用属性控制 XML 序列化. 这些属性还可 ...
- 《深入了解 Linq to SQL》之对象的标识 —— 麦叔叔呕心呖血之作
序言 很多朋友都向我提过,希望我写一下关于Linq to SQL 或者 VS 插件方面的文章.尽管市面上有很多 Linq to SQL 的书籍,但是都是介绍怎么用,缺乏深度.关于 VS 插件方面的书籍 ...
- sqlserver 创建索引
语法:CREATE [索引类型] INDEX 索引名称ON 表名(列名)WITH FILLFACTOR = 填充因子值0~100GO /*实例*/ CREATE NONCLUSTERED INDEX ...
- 重大新闻:借贷宝不用绑卡了,借贷宝APP推出肖像识别新功能!
动动手指,20元人民币立即到手:http://www.cnblogs.com/mfryf/p/4754384.html 滴滴打车烧钱十几个亿,狂送打车券,很多人天天免费坐车! 去年年初百度钱包注册奖励 ...
- ViewPager的Adapter中视图重用
ViewPager的PagerAdapter不像ListView/GridView的BaseAdapter,它是没有内部视图重用机制的,也就是说我先inflate出来一个,然后调用destroyIte ...
- [bzoj2301: [HAOI2011]Problem b] 乞讨
</pre><pre code_snippet_id="507886" snippet_file_name="blog_20141104_2_53831 ...
- 关于vnc连接闪退问题的设置
设置如下: 依次点Option-->Advanced-->Expert找到ColourLevel,默认值是pal8,修改为rgb222或full.
- idea maven jetty插件热部署
maven tomcat插件好像无法进行热部署,jetty可以如下配置实现热部署,但是idea无法进行自动编译,所以需要如下快捷键 Ctrl+Shift+F9,编译 Ctrl+F9,生成项目 < ...
- C#操作注册表——读、写、删除、判断等基本操作
一.引入命名空间: using Microsoft.Win32; 二.创建注册表项:CreateSubKey(name)方法 添加SubKey时候首先要打开一个表项,并设置参数为true,才能成功创建 ...
- UVa 11488 - Hyper Prefix Sets
找 前缀长度*符合该前缀的字符串数 的最大值 顺便练了一下字典树的模板 #include <iostream> #include <cstdio> #include <c ...