算法实践--最小生成树(Prim算法)
前一篇介绍了一种最小生成树的算法--Kruskal算法,本篇介绍另一种Prim算法
算法描述
定义V为端点的集合,A为最小生成树,初始为空。对于每个端点v初始的Key[v]=∞, Parent[v]=null
初始化Q为V, 指定任意一个端点为root,其值Key[r]=0
while(Q不为空) {
找出Q中Key值最小的u
Q = Q - u
if (PARENT[u] != null) {
将(u, Parent(u))加入A中
}
foreach(u的相邻端点v) {
if (v在Q中且w(u, v) < Key[v]) {
PARENT[v] = u;
Key[v] = w;
}
}
return A
图片示例
初始状态

选择一个端点a作为root

找出Q中Key最小的a,将其从Q中删除,同时更新其相邻端点b和f的Key和PARENT

找出Q中Key最小的f, 从Q中删除,因为f的父节点为a,将(a, f)加到A中。同时更新f相邻节点的Key和父节点

Q减去c,A加上(c ,f), 更新相邻节点d的Key和父节点

Q减去b,A加上(b, f)

Q减d,A加(c, d)

Q减e,A加(d, e)

C++代码实现
struct Edge {
char vertex1;
char vertex2;
int weight;
Edge(char v1, char v2, int w):vertex1(v1), vertex2(v2), weight(w) {}
};
struct Graph {
vector<char> vertice;
vector<Edge> edges;
vector< pair<char, Edge> > adjacent(char u) { // 返回端点u所有相邻的端点及权重
vector< pair<char, Edge> > res;
for (Edge e : edges) {
if (e.vertex1 == u) {
res.push_back( make_pair(e.vertex2, e));
} else if (e.vertex2 == u) {
res.push_back( make_pair(e.vertex1, e));
}
}
return res;
}
};
void prim(Graph& g, char root) {
unordered_map<char, char> res;
unordered_map<char, char> PARENT;
unordered_map<char, int> KEY;
for (auto c : g.vertice) {
PARENT[c] = '\0';
KEY[c] = INT_MAX;
}
KEY[root] = ;
vector<char> Q = g.vertice;
while (!Q.empty()) { // O(V)
char u = *std::min_element(Q.begin(), Q.end(), [&](char x, char y) {return KEY[x] < KEY[y];}); // O(v)
vector<char>::iterator itr = remove(Q.begin(), Q.end(), u); // O(V)
Q.erase(itr, Q.end()); // erase() following remove() idiom
if (PARENT[u] != '\0') {
res[u] = PARENT[u]; // This is one edge of MST
}
vector< pair<char, Edge> > adj = g.adjacent(u); // O(E)
for (pair<char, Edge> v : adj) {
if (find(Q.begin(), Q.end(), v.first) != Q.end()) { // O(V)
if (v.second.weight < KEY[v.first]) {
PARENT[v.first] = u;
KEY[v.first] = v.second.weight;
}
}
}
}
for (auto e : res) {
cout << e.first << " -- " << e.second << endl;
}
}
int main() {
Graph g;
char t[] = {'a', 'b', 'c', 'd', 'e', 'f'};
g.vertice = vector<char>(t, t + sizeof(t)/sizeof(t[]));
g.edges.push_back(Edge('a', 'b', ));
g.edges.push_back(Edge('a', 'f', ));
g.edges.push_back(Edge('f', 'b', ));
g.edges.push_back(Edge('c', 'b', ));
g.edges.push_back(Edge('c', 'f', ));
g.edges.push_back(Edge('f', 'e', ));
g.edges.push_back(Edge('d', 'e', ));
g.edges.push_back(Edge('d', 'c', ));
prim(g, 'a');
return ;
}
算法实践--最小生成树(Prim算法)的更多相关文章
- 算法实践--最小生成树(Kruskal算法)
什么是最小生成树(Minimum Spanning Tree) 每两个端点之间的边都有一个权重值,最小生成树是这些边的一个子集.这些边可以将所有端点连到一起,且总的权重最小 下图所示的例子,最小生成树 ...
- 数据结构代码整理(线性表,栈,队列,串,二叉树,图的建立和遍历stl,最小生成树prim算法)。。持续更新中。。。
//归并排序递归方法实现 #include <iostream> #include <cstdio> using namespace std; #define maxn 100 ...
- 最小生成树Prim算法(邻接矩阵和邻接表)
最小生成树,普利姆算法. 简述算法: 先初始化一棵只有一个顶点的树,以这一顶点开始,找到它的最小权值,将这条边上的令一个顶点添加到树中 再从这棵树中的所有顶点中找到一个最小权值(而且权值的另一顶点不属 ...
- 最小生成树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind
最小支撑树树--Prim算法,基于优先队列的Prim算法,Kruskal算法,Boruvka算法,“等价类”UnionFind 最小支撑树树 前几节中介绍的算法都是针对无权图的,本节将介绍带权图的最小 ...
- 最小生成树—prim算法
最小生成树prim算法实现 所谓生成树,就是n个点之间连成n-1条边的图形.而最小生成树,就是权值(两点间直线的值)之和的最小值. 首先,要用二维数组记录点和权值.如上图所示无向图: int map[ ...
- HDU1102 最小生成树prim算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:给出任意两个城市之间建一条路的时间,给出哪些城市之间已经建好,问最少还要多少时间使所有的城 ...
- Highways POJ-1751 最小生成树 Prim算法
Highways POJ-1751 最小生成树 Prim算法 题意 有一个N个城市M条路的无向图,给你N个城市的坐标,然后现在该无向图已经有M条边了,问你还需要添加总长为多少的边能使得该无向图连通.输 ...
- SWUST OJ 1075 求最小生成树(Prim算法)
求最小生成树(Prim算法) 我对提示代码做了简要分析,提示代码大致写了以下几个内容 给了几个基础的工具,邻接表记录图的一个的结构体,记录Prim算法中最近的边的结构体,记录目标边的结构体(始末点,值 ...
- 图论算法(五)最小生成树Prim算法
最小生成树\(Prim\)算法 我们通常求最小生成树有两种常见的算法--\(Prim\)和\(Kruskal\)算法,今天先总结最小生成树概念和比较简单的\(Prim\)算法 Part 1:最小生成树 ...
- 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析
最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析 最小生成树,老生常谈了,生活中也总会有各种各样的问题,在这里,我来带你一起分析一下这个算法的思路与实现的方式吧~~ 在考研中呢 ...
随机推荐
- 『Python CoolBook』使用ctypes访问C代码_上_用法讲解
一.动态库文件生成 源文件hello.c #include "hello.h" #include <stdio.h> void hello(const char *na ...
- Python- - -基础目录
一.Python.pycharm的介绍与安装. 二.变量.整数.字符串.列表.字典.集合. 三.运算符.格式化输出.流程控制语句. 四.break和continue. 五.range.enumerat ...
- day058 聚合 分组查询 自定义标签过滤器 外部调用django环境 事务和锁
1.聚合(aggregate) 聚合的主要语法: from django.db.models import Avg , Max , Min , Count models.类名 .objects.all ...
- 使用Python爬取代理ip
本文主要代码用于有代理网站http://www.kuaidaili.com/free/intr中的代理ip爬取,爬虫使用过程中需要输入含有代理ip的网页链接. 测试ip是否可以用 import tel ...
- LeetCode 81 搜索旋转排序数组II
题目: 假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,0,1,2,2,5,6] 可能变为 [2,5,6,0,0,1,2] ). 编写一个函数来判断给定的目标值是否存在于 ...
- Linux Shell基础(下)
Linux Shell基础(下) 目录 一.shell特殊符号cut命令 二.cut.sort.wc.uniq命令 三.tee.tr.split命令 四.简易审计系统 五.fork, exec, so ...
- 2D过渡模块的其他属性
官网上关于过渡属性的值: 属性 描述 CSS transition 简写属性,用于在一个属性中设置四个过渡属性. 3 transition-property 规定应用过渡的 CSS 属性的名称. 3 ...
- Linux 驱动——从宏观上掌握基本框架
一.一个简单的驱动程序实例 led_drv.c 驱动文件: #include <linux/module.h>#include <linux/kernel.h>#include ...
- Beta周王者荣耀交流协会第四次Scrum会议
1.立会照片 成员王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:任思佳 2.时间跨度: 2017年11月13日 11:40 — 12:10 ,总计30分钟. 3.地点: 一食 ...
- 使用ssh免密登录
在开发中经常会遇到远程登录服务器,要经常输入密码.有时密码太复杂记不住,还需要保存到本地文件中. 可以使用ssh命令,配置密钥登录,这样就不需要输入密码,一劳永逸,何乐而不为 ^--^ 配置密钥只需要 ...