Minimum Spanning Tree
前言
说到最小生成树(Minimum Spanning Tree),首先要对以下的图论概念有所了解。
图
图(Graph)是表示物件与物件之间的关系的数学对象,是图论的基本研究对象。图的定义方式有两种,其一是二元组定义。图G是一个有序二元组(V,E),其中V称为顶集(Vertices Set),E称为边集(Edges set),E与V不相交。它们亦可写成V(G)和E(G)。
边的方向
边是有方向的,单方向(如只允许从点a到达点b)的边称为单向边或有向边;允许双方互达的边称为双向边或无向边。包含单向边的图称为单向图,不包含单向边的称为无向图。
带权图
图上的边或者点都可以带有权值,带权值的图就称为带权图。
子图
任取图G的若干点,以及这些点在G中存在的若干边构成的集合称为G的子图。
连通图
如果无向图G的任意点都可以直接或间接地到达其余所有点,那么G就称为连通图。
树
树是一种特殊的图,树上的所有点与其他点之间有且仅有一条直接或间接路径。性质:|V|=|E|+1。
生成树
如果连通图G的一个子图是一棵包含G的所有顶点的树,则该子图称为G的生成树。显然对于同一个图,生成树并不唯一。
最小生成树
定义
图G的最小生成树(假设存在)是边权和最小的生成树。
算法
Prim和Kruskal
Prim
Prim又称加点法。
步骤
•在G中任意选取一个结点v_1,置V={v_1},E=∅,k=1
•在V-V中选取与某个v_i ∈V邻接的结点v_j ,使得边(v_i , v_j)权值最小,置V=V∪{v_j },E=E∪{(v_i ,v_j )},k=k+1
•重复第二步,直到k=|V|
复杂度
$$
O(\mid V\mid^2)
$$
模板
// cost 0~n-1
// 不连通 return -1
const int INF = 0x3f3f3f3f;
const int MAXN = 110;
bool vis[MAXN];
int lowc[MAXN];
int Prim(int cost[][MAXN], int n) {
int ans = 0;
memset(vis, false, sizeof(vis));
vis[0] = true;
for (int i = 1; i < n; i++)
lowc[i] = cost[0][1];
for (int i = 1; i < n; i++) {
int minc = INF;
int p = -1;
for (int j = 0; j < n; j++) {
if (!vis[j] && minc > lowc[j]) {
minc = lowc[j];
p = j;
}
}
if (minc == INF) {
return -1;
}
ans += minc;
vis[p] = true;
for (int j = 0; j < n; j++) {
if (!vis[j] && lowc[j] > cost [p][j]) {
lowc[j] = cost[p][j];
}
}
}
return ans;
}
Kruskal
Kruskal又称加边法。
步骤
•在G中选取最小权边e_1,置i=1
•当i=n-1时,结束,否则进行下一步
•设已选取的边为e_1 ,e_2,……, e_i ,在G中选取不同于以上的边e_i+1,使得{e_1 ,e_2,……, e_i , e_i+1}中无回路且e_i+1是满足此条件的最小权边。
•置i=i+1,转第二步
复杂度
$$
O(\mid E\mid \log \mid E \mid)
$$
模板
const int MAXM = 10000; // 边
const int MAXN = 110; // 点
int F[MAXN]; // 并查集
struct Edge {
int u, v, w; // 起点、终点、权值
}edge[MAXN];
int tol; // 边数,加边算法,初始为零
void AddEdge(int u, int v, int w) {
edge[tol].u = u;
edge[tol].v = v;
edge[tol++].w = w;
}
bool CMP(Edge a, Edge b) {
return a.w < b.w;
}
int Find(int x) {
return x == F[x] ? x : F[x] = Find(x);
}
// n 为图的点总数
int Kruskal(int n) {
memset(F, -1, sizeof(F));
sort(edge, edge + tol, CMP);
int cnt = 0, ans = 0;
for (int i = 0; i < tol; i++) {
int u = edge[i].u;
int v = edge[i].v;
int w = edge[i].w;
int t1 = Find(u);
int t2 = Find(v);
if (t1 != t2) {
ans += w;
F[t1] = t2;
cnt++;
}
if (cnt == n - 1) {
break;
}
}
return cnt < n - 1 ? -1 : ans;
}
Minimum Spanning Tree的更多相关文章
- 【HDU 4408】Minimum Spanning Tree(最小生成树计数)
Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...
- 数据结构与算法分析–Minimum Spanning Tree(最小生成树)
给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree). 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Mi ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA/(树链剖分+数据结构) + MST
E. Minimum spanning tree for each edge Connected undirected weighted graph without self-loops and ...
- CF# Educational Codeforces Round 3 E. Minimum spanning tree for each edge
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值
E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...
- MST(Kruskal’s Minimum Spanning Tree Algorithm)
You may refer to the main idea of MST in graph theory. http://en.wikipedia.org/wiki/Minimum_spanning ...
- HDU 4408 Minimum Spanning Tree 最小生成树计数
Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树
E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...
- 说说最小生成树(Minimum Spanning Tree)
minimum spanning tree(MST) 最小生成树是连通无向带权图的一个子图,要求 能够连接图中的所有顶点.无环.路径的权重和为所有路径中最小的. graph-cut 对图的一个切割或者 ...
随机推荐
- 读BeautifulSoup官方文档之html树的搜索(2)
除了find()和find_all(), 这里还提供了许多类似的方法我就细讲了, 参数和用法都差不多, 最后四个是next, previous是以.next/previous_element()来说的 ...
- Windows证书的生成导出以及使用证书验证文件是否被修改
本文介绍了如何使用Windows自带的证书生成器生成,导出,使用证书.并以验证文件是否被修改举例 1.证书相关辅助类 public sealed class DataCertificate { #re ...
- WPF生成二维码
WPF可以通过ZXing.Net库来实现二维码的功能. 可以通过NuGet安装: Install-Package ZXing.Net 二维码的实现代码: #region 二维码的方法 /// < ...
- Quartz Cron 生成工具
/** * 每周期 */ function everyTime(dom) { var item = $("input[name=v_" + dom.name + "]&q ...
- QSocket 总体设计框架说明(观赏)
QSocket 是 QDAC 开源组件的一个重要的组成部分,终于要开始开工了,为了方便大家了解 QSocket,对 QSocket 的总体设计的一些想法,我在这里给大家简要的描述一下. 首先,QSoc ...
- qt中采用宽带speex进行网络语音通话实验程序
qt中采用宽带speex进行网络语音通话实验程序 本文博客链接:http://blog.csdn.NET/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN8 开发环境:Qt5 3.1. ...
- Qt优雅地结束线程(两种方法都是用Mutex锁住bool变量进行修改,然后由bool变量控制耗时动作的退出,即正常退出)
如果一个线程运行完成,就会结束.可很多情况并非这么简单,由于某种特殊原因,当线程还未执行完时,我们就想中止它.不恰当的中止往往会引起一些未知错误.比如:当关闭主界面的时候,很有可能次线程正在运行,这时 ...
- RequestMapping原理分析和RequestMappingHandlerMapping
转载https://juejin.im/post/5cbeadb96fb9a031ff0d18b5 源码版本spring-webmvc-4.3.7.RELEASE 使用Spring MVC的同学一般都 ...
- Mybatis_three
延迟加载 实现多对一的延迟加载(association) 例如下面的:有很多个账户信息(招商\工商\农商)是属于一个用户人的 [需求] 查询账户(Account)信息并且关联查询用户(User)信息. ...
- Docker-CE 安装(centos7)
配置yum源 > cd /etc/yum.repos.d/ > mkdir repo_bak > mv *.repo repo_bak/ > wget http://mirro ...