文章目录

  • Kruskal算法
    • 模板:https://blog.csdn.net/Rain722/article/details/65642992
  • Prim算法
    • 模板:
  • poj 1251 JungleRoad

Kruskal算法

模板:https://blog.csdn.net/Rain722/article/details/65642992

Kruskal是另一个计算最小生成树的算法,其算法原理如下。首先,将每个顶点放入其自身的数据集合中。然后,按照权值的升序来选择边。当选择每条边时,判断定义边的顶点是否在不同的数据集中。如果是,将此边插入最小生成树的集合中,同时,将集合中包含每个顶点的联合体取出,如果不是,就移动到下一条边。重复这个过程直到所有的边都探查过。

下面还是用一组图示来表现算法的过程:
1 初始情况,一个联通图,定义针对边的数据结构,包括起点,终点,边长度:

2 继续找到第二短的边,将c, d再放入同一个集合里:

3 继续找,找到第三短的边ab,因为a,e已经在一个集合里,再将b加入:

4 继续找,找到b,e,因为b,e已经同属于一个集合,连起来的话就形成环了,所以边be不加入最小生成树:

5 再找,找到bc,因为c,d是一个集合的,a,b,e是一个集合,所以再合并这两个集合:

这样所有的点都归到一个集合里,生成了最小生成树。


Prim算法

模板:

https://blog.csdn.net/vvvzcs/article/details/74538525
https://blog.csdn.net/Fantasy_World/article/details/82935604

算法描述:

  1. 在一个加权连通图中,顶点集合V,边集合为E
  2. 任意选出一个点作为初始顶点,标记为visit,计算所有与之相连接的点的距离,选择距离最短的,标记visit.
  3. 重复以下操作,直到所有点都被标记为visit:
    在剩下的点钟,计算与已标记visit点距离最小的点,标记visit,证明加入了最小生成树。

下面我们来看一个最小生成树生成的过程:
1 起初,从顶点a开始生成最小生成树

2 选择顶点a后,顶点啊置成visit(涂黑),计算周围与它连接的点的距离:

3 与之相连的点距离分别为7,6,4,选择C点距离最短,涂黑C,同时将这条边高亮加入最小生成树:

4 计算与a,c相连的点的距离(已经涂黑的点不计算),因为与a相连的已经计算过了,只需要计算与c相连的点,如果一个点与a,c都相连,那么它与a的距离之前已经计算过了,如果它与c的距离更近,则更新距离值,这里计算的是未涂黑的点距离涂黑的点的最近距离,很明显,b和a为7,b和c的距离为6,更新b和已访问的点集距离为6,而f,e和c的距离分别是8,9,所以还是涂黑b,高亮边bc:

5 接下来很明显,d距离b最短,将d涂黑,bd高亮:

6 f距离d为7,距离b为4,更新它的最短距离值是4,所以涂黑f,高亮bf:

7 最后只有e了:


poj 1251 JungleRoad

题意:&Input:
n个村庄,n-1行数据:村子u,通往其他x个村子的道路条数,终点村子v,u到v的路途w

Output:
求最小耗费(最小生成树

思路:
Kruskal、Prim

Kruskal:

  Kruskal:#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int maxn = 50;struct edge
{int u, v, w;
};
bool cmp(edge a, edge b)
{return a.w < b.w;
}int n;
int par[maxn];
edge road[2 * maxn];
int cnt = 0;//记录边的条数
int ans = 0;int find(int x)
{if (par[x] == x)return par[x];return par[x] = find(par[x]);
}
void initialize()
{cnt = 0;ans = 0;for (int i = 0; i < n; i++)par[i] = i;
}int main()
{while (cin >> n && n != 0){initialize();for (int i = 0; i < n - 1; i++){char s; int num;cin >> s >> num;for (int i = 0; i < num; i++){char e; int w;cin >> e >> w;road[cnt].u = s - 'A';road[cnt].v = e - 'A';road[cnt].w = w;cnt++;}}sort(road, road + cnt, cmp);for (int i = 0; i < cnt; i++){int fa = find(road[i].u);int fb = find(road[i].v);if (fa != fb){//par[fb] = fa;par[fa] = fb;//两种都行ans += road[i].w;}}cout << ans << endl;}return 0;
}

Prim:
假设某步已经找到了最小生成树的一部分G,dis记录的是其它每点到G(最小生成树)中最短的距离。

//  Prim;
#include<iostream>
#include<string>
#include<cmath>
#include<ctype.h>
#include<memory.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<iomanip>
#include<set>
#include<list>
#include<vector>
#include<stack>
#include<queue>
#define ll long long int
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 50;
int n;
int Map[maxn][maxn];
int dis[maxn];
int vis[maxn];int prim()
{memset(vis, 0, sizeof(vis));for (int i = 0; i < n; i++)dis[i] = Map[0][i];for (int i = 0; i < n; i++){int Min = INF, min_index = -1;for (int j = 0; j < n; j++){if (dis[j] < Min && !vis[j]){Min = dis[j];min_index = j;}}vis[min_index] = 1;for (int j = 0; j < n; j++){if (dis[j] > Map[min_index][j] && !vis[j])dis[j] = Map[min_index][j];}}int ans = 0;for (int i = 0; i < n; i++)ans += dis[i];return ans;
}int main()
{while (cin >> n && n != 0){for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)Map[i][j] = i == j ? 0 : INF;for (int i = 0; i < n - 1; i++){char u; int num; cin >> u >> num;//cout << num << " ";for (int j = 0; j < num; j++){char v; int w; cin >> v >> w;Map[u - 'A'][v - 'A'] = Map[v - 'A'][u - 'A'] = w;}}cout << prim() << endl;}return 0;
}

* poj 1251 JungleRoad 最小生成树 Kruskal算法、Prim算法相关推荐

  1. 最小生成树 Kruskal 和 Prim算法及堆优化

    目录 生成树/最小生成树是什么. 一.Kruskal算法 Kruskal模板 二.Prim算法及堆优化 1.遍历 Prim 普通模板 2.堆优化 Prim 堆优化模板 解决最小生成树的问题之前,我们先 ...

  2. poj 3026 BorgMaze 最小生成树Kruskal、Prim(Prim VS报错待解决

    题意 以及 思路: 从S点有一伙人出发去消灭A点的敌人,在S点或者A点可以分裂成几个小队然后分别走,这样路径=总队路径+各个小队路径 问你怎样路径最短. 在一个y行 x列的迷宫中,有可行走的通路空格' ...

  3. poj 1789 TruckHistory 最小生成树 Kruskal、Prim

    题意: n个车牌号,刚开始只有一个车牌,其他车牌都是由一个车牌直接或间接产生,一个车牌到另一个车牌的产生权值是它们之间的数字不同的个数,问产生的最小的边权和,即求最小生成树. Input: 多组数据. ...

  4. 生成top图_最小生成树(Kruskal和Prim算法)

    文章和资源同步更新至微信公众号:算法工程师之路 8月份会开启每日算法题系列,值得期待哦 上一篇文章,我们讲了图的创建和遍历,其中遍历的算法主要有BFS(广度优先算法)和DFS(深度优先算法)两种,并且 ...

  5. prim算法_最小生成树(Kruskal和Prim算法)

    文章和资源同步更新至微信公众号:算法工程师之路 8月份会开启每日算法题系列,值得期待哦 上一篇文章,我们讲了图的创建和遍历,其中遍历的算法主要有BFS(广度优先算法)和DFS(深度优先算法)两种,并且 ...

  6. 【老生谈算法】matlab实现Kruskal避圈算法求最小生成树——Kruskal避圈算法

    基于MATLAB的Kruskal避圈算法求最小生成树 1.原文下载: 本算法原文如下,有需要的朋友可以点击进行下载 序号 原文(点击下载) 本项目原文 [老生谈算法]基于MATLAB的Kruskal避 ...

  7. Java实现最小生成树算法(Prim算法)

    Prim算法 Prim算法,每一步都会为一颗生长中的树添加一条边.一开始这棵树只有一个顶点,然后哦会向它添加V-1条边,每次总是将下一条连接树的顶点与不在树中且权重最小的边加入树中 实现 最小生成树的 ...

  8. 贪心算法prim算法

    普利姆算法(Prim): 算法思想基于顶点选择,通过维护两个点集,已选点集S和未选点集T,每次选择从S集映射到T集的最小代价边,适用于稠密图. 图解dis更新过程: 最短路径求解时,dis更新的都是以 ...

  9. 最小生成树(Kruskal和Prim算法)

    一.先再次明确关于图的几个概念定义: 连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图. 强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称 ...

最新文章

  1. OpenGL中关于坐标系原点在左上角还是左下角的一些整理
  2. matlab绘图 subplot函数使用方法
  3. C++类class和结构体struct区别
  4. 趣味编程:函数式链表的快速排序
  5. 怎么查看和修改 MySQL 的最大连接数?
  6. js oop写法小例子
  7. Java基于springMVC的验证码案例
  8. UOJ59 WC2013 小Q运动季
  9. HDU2017 字符串统计【入门】
  10. python入门先学什么-C和Python我该先学什么?
  11. SpriteBuilder改变布局后App运行出错代码排查
  12. 日期Date和String/Long之间的转换
  13. hive 常用函数操作
  14. 好文推荐:努力是没有用的
  15. python中pos什么意思_python pos是什么
  16. Anaconda conda常用命令:从入门到精通
  17. VRF在区块链中的应用
  18. SLAM基础问题总结(1)
  19. 关于java多参数的传值问题解析
  20. 利用计算机打字教学设计,小学信息技术第2节用电脑打字8课时教学设计.pdf

热门文章

  1. 51单片机学习笔记(郭天祥版)(3)——引脚讲解、数码管静态显示、中断系统(外部中断,定时器中断)...
  2. 2151: 种树 - BZOJ
  3. oracle 11g 如何实现坏块检查、恢复?
  4. switch java 语法_Java_基础语法之switch语句
  5. 贪心策略——部分背包问题
  6. C语言课后习题(15)
  7. python导入类属性不存在_为什么我会得到一个错误:我的类中不存在该属性?
  8. PGer看过来!亚洲最大的PG技术盛会重磅来袭!墨天轮全球同步直播!
  9. 快来一起玩转LiteOS组件:Curl
  10. 云小课|CDN第5课 CDN入门之—我的网站可以用CDN加速吗?