推荐:http://squirrelrao.iteye.com/blog/1044867

   http://www.cnblogs.com/xwdreamer/archive/2011/06/16/2296997.html

  http://blog.csdn.net/believejava/article/details/17414037

一、Prim算法:

Prim算法实现的是找出一个有权重连通图中的最小生成树,即:具有最小权重且连接到所有结点的树。(强调的是树,树是没有回路的)。

Prim算法是这样来做的:

首先以一个结点作为最小生成树的初始结点,然后以迭代的方式找出与最小生成树中各结点权重最小边,并加入到最小生成树中。加入之后如果产生回路则跳过这条边,选择下一个结点。当所有结点都加入到最小生成树中之后,就找出了连通图中的最小生成树了。

/*
prim 最小生成树算法
过程:prim算法将图分为两部分,假设原顶点集为V,将其分为S和V-S两部分,S为已经确定在最小生成树上的顶点,
开始时,将任意一个顶点加入到S,然后每次在V-S中寻找距离S中的点最近的点。作为下一个加入最小生成树上的点。
所有N个节点都加入到最小生成树中时,最小生成树构造完毕。 实现:对于邻接矩阵构造的图,可以用low[N]保存每个顶点到已加入生成树中所有点的最小距离。
每次寻找这个距离最小的一个点加入最小生成树中。再根据这个点的距离更新其它未加入生成树中的点。
直到所有的点都加入到最小生成树中。
*/ // Eg:HDU 1102 #include <stdio.h>
#include <string.h>
#include <iostream>
#define inf 1000000
using namespace std; int g[210][210];
int low[210];
int vis[210]; // 表示该点是否已经加入最小生成树中
int n; int prim() {
for (int i=0; i<n; ++i) {
low[i] = g[0][i];
} int ans = 0;
memset(vis, 0, sizeof(vis));
vis[0] = 1; for (int i=1; i<n; ++i) { // 循环n-1次,找剩下的n-1个点。
int k = -1, mindis = inf;
for (int j=0; j<n; ++j) { // 循环找当前剩下的点中 距离最小生成树点集距离最短的点。
if (!vis[j] && low[j] < mindis) {
mindis = low[j];
k = j;
}
} if (k == -1) return -1;
vis[k] = 1; // 加入最小生成树点集
ans += mindis; for (int j=0; j<n; ++j) { // 更新没加入最小生成树的点中 距离是否会缩短。
/*if (!vis[j] && low[j] > low[k] + g[k][j]) {
low[j] = low[k] + g[k][j];
}*/ if (!vis[j] && low[j] > g[k][j]) { // 上面的if是错的。low数组存储的距离是当前点到生成树中所有点距离最小的的点。
low[j] = g[k][j]; // 因为这个点加入最小生成树集合中,可以和其中任意一个点连一条边。
}
}
}
return ans;
} int main() {
int q;
while(cin >> n) {
for (int i=0; i<n; ++i) {
for (int j=0; j<n; ++j) {
cin >> g[i][j];
}
} cin >> q;
for (int i=0; i<q; ++i) {
int a, b;
cin >> a >> b;
a--, b--;
g[a][b] = 0;
g[b][a] = 0;
} int ans = prim();
cout << ans << endl;
}
return 0;
}

  

二、Kruskal算法:

Kruskal算法与Prim算法的不同之处在于,Kruskal在找最小生成树结点之前,需要对所有权重边做从小到大排序。将排序好的权重边依次加入到最小生成树中,如果加入时产生回路就跳过这条边,加入下一条边。当所有结点都加入到最小生成树中之后,就找出了最小生成树。

无疑,Kruskal算法在效率上要比Prim算法快,因为Kruskal只需要对权重边做一次排序,而Prim算法则需要做多次排序。尽管Prim算法每次做的算法涉及的权重边不一定会涵盖连通图中的所有边,但是随着所使用的排序算法的效率的提高,Kruskal算法和Prim算法之间的差异将会清晰的显性出来。

/*
最小生成树 kruskal算法
过程:每次选取没有参与构造最小生成树并且加入之后不会构成回路的边中权值最小的一条
作为最小生成树的一条新边。直至选择了V-1条边。
*/ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define maxn 2100
using namespace std; int fa[maxn], r[maxn]; void init(int n) {
for (int i=1; i<=n; ++i) {
fa[i] = i;
r[i] = 1;
}
} int find_fa(int v) { // 递归式路径压缩
if (fa[v] != v) fa[v] = find_fa(fa[v]);
return fa[v];
} /*int find_fa(int v) { // 非递归式路径压缩
int k, j, r;
r = v;
while(r != fa[r])
r = fa[r]; //找到根节点 记录在r上。
k = v;
while(k != r) {
j = fa[k];
fa[k] = r;
k = j;
}
return r;
}*/ /*void unin(int u, int v) { // 非按秩合并
int fau = find_fa(u);
int fav = find_fa(v);
if (fau != fav)
fa[fav] = fau;
}*/ void unin(int u, int v) { // 按秩合并
int fau = find_fa(u);
int fav = find_fa(v);
if (fau == fav) return; if (r[u] < r[v]) fa[fau] = fav;
else {
if (r[u] == r[v])
r[u]++;
fa[fav] = fau;
}
} struct Edge {
int u, v, w;
}edge[1000010]; bool cmp(Edge a, Edge b) {
return a.w > b.w;
} int ans;
int kruskal(int n, int m) { // 传入顶点个数n 和 边的个数m
init(n);
sort(edge, edge+m, cmp);
ans = 0;
int ret = 0; // 生成树的总权值
int cnt = 0; // 已加入最小生成树的边的数量 for (int i=0; i<m; ++i) {
if (find_fa(1) == find_fa(n)) return -1;
int u = edge[i].u;
int v = edge[i].v;
if (find_fa(u) != find_fa(v)) {
cnt++;
ret += edge[i].w;
unin(u, v);
ans = edge[i].w;
}
if (cnt == n-1) return ret; // 已找到n-1条边,生成树构造完毕
}
return -1;
} int main() {
int casee = 1;
int t;
cin >> t;
while(t--) {
int n, m;
cin >> n >> m;
for (int i=0; i<m; ++i) {
cin >> edge[i].u >> edge[i].v >> edge[i].w;
}
kruskal(n, m);
cout << "Scenario #" << casee++ << ":" << endl << ans << endl << endl;
}
return 0;
}

  

关于时间复杂度:

prim:该算法的时间复杂度为O(n2)。与图中边数无关,该算法适合于稠密图。

kruskal:需要对图的边进行访问,所以克鲁斯卡尔算法的时间复杂度只和边又关系,可以证明其时间复杂度为O(eloge)。适合稀疏图。

prim和kruskal比较的更多相关文章

  1. Prim和Kruskal最小生成树

    标题: Prim和Kruskal最小生成树时 限: 2000 ms内存限制: 15000 K总时限: 3000 ms描述: 给出一个矩阵,要求以矩阵方式单步输出生成过程.要求先输出Prim生成过程,再 ...

  2. 【图论】信手拈来的Prim,Kruskal和Dijkstra

    关于三个简单的图论算法 prim,dijkstra和kruskal三个图论的算法,初学者容易将他们搞混,所以放在一起了. prim和kruskal是最小生成树(MST)的算法,dijkstra是单源最 ...

  3. 图的最小生成树的理解和实现:Prim和Kruskal算法

    最小生成树 一个连通图的生成树是一个极小的连通子图,它含有图中所有的顶点,但只有足以构成一棵树的n-1条边.我们将构造连通网的最小代价生成树称为最小生成树(Minimum Cost Spanning ...

  4. 最小生成树(prim和kruskal)

    最小生成树(prim和kruskal) 最小生成树的最优子结构性质 设一个最小生成树是T.如果选出一个T中的一条边,分裂成的两个树T1,T2依然是它们的点集组成的最小生成树.这可以用反证法来证.反着来 ...

  5. HDU 3080 The plan of city rebuild(prim和kruskal)

    The plan of city rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  6. 最小生成树,Prim和Kruskal的原理与实现

    文章首先于微信公众号:小K算法,关注第一时间获取更新信息 1 新农村建设 大清都亡了,我们村还没有通网.为了响应国家的新农村建设的号召,村里也开始了网络工程的建设. 穷乡僻壤,人烟稀少,如何布局网线, ...

  7. 最小生成树MST算法(Prim、Kruskal)

    最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...

  8. Prim和Kruskal求最小生成树

    Prim: 算法步骤: 1.任意结点开始(不妨设为v1)构造最小生成树: 2.首先把这个结点(出发点)包括进生成树里, 3.然后在那些其一个端点已在生成树里.另一端点还未在生成树里的所有边中找出权最小 ...

  9. hdu_1875_畅通工程再续 prim和kruskal

    这个题是个典型的最小生成树的题目,但是刚开始怎么都过不了,后来发现两种写法都有疏忽,但是prim的到目前为止不懂为什么刚开始的不对,kruskal算法,并查集的初始条件从0开始写成从1开始了,所以已知 ...

  10. 图的最小生成树(Prim、Kruskal)

    理论: Prim: 基本思想:假设G=(V,E)是连通的,TE是G上最小生成树中边的集合.算法从U={u0}(u0∈V).TE={}开始.重复执行下列操作: 在所有u∈U,v∈V-U的边(u,v)∈E ...

随机推荐

  1. (2.14)Mysql之SQL基础——游标

    (2.14)Mysql之SQL基础——游标 关键词:Mysql游标 -- (1)定义游标 declare cur_name cursor for select * from table_name wh ...

  2. ajax请求,html调用js

    1:html中调用js中的函数,js使用ajax请求向后台请求,返回数据. <!DOCTYPE html> <html lang="en"> <hea ...

  3. mysql数据库表的查询操作-总结

    转自:https://www.cnblogs.com/whgk/p/6149009.html 序言 1.MySQL表操作(创建表,查询表结构,更改表字段等), 2.MySQL的数据类型(CHAR.VA ...

  4. Django的FBV和CB

    Django的FBV和CBV FBV FBV(function base views) 就是在视图里使用函数处理请求. 在之前django的学习中,我们一直使用的是这种方式,所以不再赘述. CBV C ...

  5. Q_OBJECT宏的作用

    The Q_OBJECT macro at the beginning of the class definition is necessary for all classes that define ...

  6. 自定义 Repository 方法

    为某一个 Repository 上添加自定义方法 步骤: 定义一个接口: 声明要添加的, 并自实现的方法 提供该接口的实现类: 类名需在要声明的 Repository 后添加 Impl, 并实现方法 ...

  7. cocos代码研究(15)Widget子类CheckBox学习笔记

    理论基础 复选框是一种特定类型的“两状态”按钮,可以处于“选中”和“未选中状态”.继承自AbstractCheckButton.注 AbstractCheckButton继承自Widget类. 代码部 ...

  8. IntelliJ idea的初次使用

    1. 首次使用Idea工具,需要安装.我安装的版本是14.0.2.安装包下载地址 http://pan.baidu.com/s/1gfFkrzt 2. 安装SVN. 3.配置JDK. 4.配置mave ...

  9. Struts2中struts.multipart.maxSize配置

    今天使用Struts2的文件上传控件时,在struts.xml中,将处理上传的action中的fileUpload拦截器的maximumSize参数设置为5000000,上传了一个3M的文件后发现控制 ...

  10. bzoj1615 / P2903 [USACO08MAR]麻烦的干草打包机The Loathesome Hay Baler

    P2903 [USACO08MAR]麻烦的干草打包机The Loathesome Hay Baler 细节题.$O(n^{2})$的$bfs$可过. #include<iostream> ...