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分钟的时间,就能完全理解. 比如:有四个村庄要修四条路,让村子能两两联系起来,这时就有最优 ...
随机推荐
- 【转】Ubuntu安装ARM架构GCC工具链(ubuntu install ARM toolchain)最简单办法
原文网址:http://www.cnblogs.com/muyun/p/3370996.html 一.安装ARM-Linux-GCC工具链 只需要一句命令: sudo apt-get install ...
- 理解最短路径——迪杰斯特拉(dijkstra)算法
原址地址:http://ibupu.link/?id=29 1. 迪杰斯特拉算法简介 迪杰斯特拉(dijkstra)算法是典型的用来解决最短路径的算法,也是很多教程中的范例,由荷兰计算机科 ...
- Mod_python: The Long Story
mod_python: the long story - Grisha Trubetskoy Mod_python: The Long Story Oct 25th, 2013 | Comments ...
- Unity扩展 自定义事件Send组件
在写项目的时候,我创建了一个方法里面需要一个int的参数. 我记得是UIEvent Trigger 不能直接传递一个数字,最多只能传递一个GameObject属性过去(=.=那个值不想再组件上定义) ...
- Beauty of Array(思维)
Beauty of Array Time Limit: 2 Seconds Memory Limit: 65536 KB Edward has an array A with N integ ...
- Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程
本文来自http://blog.csdn.net/yihongyuelan 转载请务必注明出处 本文代码以MTK平台Android 4.4为分析对象,与Google原生AOSP有些许差异,请读者知悉. ...
- Test 2.14
i am back 写博客是个好习惯啊,要坚持下去才行 这些天的日子实在堕落
- Input输入字体颜色改变js(兼容IE)
从网上找的代码,自己封装了一下(前提:引用jQuery库) 方法1: HTML: <div class="box"> <div class="ipt1& ...
- Makefiles 介绍
http://www-personal.umich.edu/~ppannuto/writings/makefiles.html Makefiles Makefiles (or, the GNU aut ...
- flex与js相互调用
1.flex调用js方法 调用方法例如:ExternalInterface.call("UploadComplete",oldName,uidName,_dir+"/&q ...