最小生成树(MST)[简述][模板]
Prim(添点法)
1. 任选一点(一般选1), 作为切入点,设其与最小生成树的距离为0(实际上就是选一个点,将此树实体化),.
2. 在所有未选择的点中选出与最小生成树距离最短的, 累计其距离, 并标为已选. 若都选择了, 则得到了最小生成树(的总路长).
3. 更新与此点相邻的点"与最小生成树的距离".返回2.
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define N 1003
#define inf 0x3f3f3f3f
struct node {
int v, w;
node () {}
node(int _v, int _w) : v(_v), w(_w) {}
};
vector<node> g[N];
int n, m, d[N];
bool vis[N]; int prim() {
memset(vis, false, sizeof(vis));
memset(d, 0x3f, sizeof(d));
int ans = d[1] = 0;
for (int i=0; i<n; i++) {
int k = 0, mi = inf;
for (int j=1; j<=n; j++) if (!vis[j] && d[j] < mi)
mi = d[j], k = j;
if (k == 0) break;
vis[k] = true;
ans += mi;
for (int j=0, u; j<g[k].size(); j++)
if (!vis[u = g[k][j].v] && d[u] > g[k][j].w)
d[u] = g[k][j].w;///和Dijkstra很像,只是这里由松弛操作改成了更新
}///此处的d表示与树的距离
return ans;///返回的是最小生成树的边长和
}
int main() { while (scanf("%d%d", &n, &m) == 2) {
for (int i=0; i<=n; i++) g[i].clear();
for (int i=0, a, b, c; i<m; i++) {
scanf("%d%d%d", &a, &b, &c);
g[a].push_back(node(b, c));
g[b].push_back(node(a, c));
}
printf("%d\n", prim());
} return 0;
}
Kruskal(添边法)
1. 将所有点加入并查集, 每个点都是独立的集合
2. 将所有边按长度排序.
3. 拿出最小边, 判断两顶点是否在同一集合, 直到边集为空. 若是, 舍弃, 返回3. 若不是, 将左顶点加入右顶点之集合(左右都是无所谓的~), 返回3.
4. 若边集为空,则得到最小生成树.
并查集按惯例使用路径压缩.
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
#define N 1002
struct node {
int u, v, w;
node() {}
node(int _u, int _v, int _w):u(_u), v(_v), w(_w) {}
};
vector<node> edge;
int n, m, f[N];
bool cmp(const node &x, const node &y) {
return x.w < y.w;
}
int find_set(int x) {
if (f[x] == x) return x;
return f[x] = find_set(f[x]);
} int Kruskal() {
sort(edge.begin(), edge.end(), cmp);
for (int i=1; i<=n; i++) f[i] = i;///将所有点加入并查集,自己是一个独立的集合
int ans = 0;
for (int i=0, u, v, w; i<edge.size(); i++) {///排序之后只要挨着拿就行
u = edge[i].u, v = edge[i].v, w = edge[i].w;
u = find_set(u), v = find_set(v);
if (u == v) continue;
f[u] = v;///这个是随便的,虽然会引起效率上的不稳定,但是一次路径压缩之后就都一样了..
ans += w;
}
return ans;
}
int main() {
while (scanf("%d%d", &n, &m) == 2) {
edge.clear();
for (int i=0, a, b, c; i<m; i++) {
scanf("%d%d%d", &a, &b, &c);
edge.push_back(node(a, b, c));///两端点是平等的,插入一次即可
}
printf("%d\n", Kruskal());
}
return 0;
}
最小生成树(MST)[简述][模板]的更多相关文章
- 最小生成树MST算法(Prim、Kruskal)
最小生成树MST(Minimum Spanning Tree) (1)概念 一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边,所谓一个 ...
- 最小生成树prime算法模板
#include<stdio.h> #include<string.h> using namespace std; int map[505][505]; int v, e; i ...
- POJ 1679 The Unique 次最小生成树 MST
http://poj.org/problem?id=1679 题目大意: 给你一些点,判断MST(最小生成树)是否唯一. 思路: 以前做过这题,不过写的是O(n^3)的,今天学了一招O(n^2)的,哈 ...
- 图的最小生成树prim算法模板
用prim算法构建最小生成树适合顶点数据较少而边较多的图(稠密图) prim算法生成连通图的最小生成树模板伪代码: G为图,一般为全局变量,数组d为顶点与集合s的最短距离 Prim(G, d[]){ ...
- 最小生成树(次小生成树)(最小生成树不唯一) 模板:Kruskal算法和 Prim算法
Kruskal模板:按照边权排序,开始从最小边生成树 #include<algorithm> #include<stdio.h> #include<string.h> ...
- 最小生成树-prim算法模板
题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M<= ...
- BZOJ 1016 最小生成树计数 【模板】最小生成树计数
[题解] 对于不同的最小生成树,每种权值的边使用的数量是一定的,每种权值的边的作用是确定的 我们可以先做一遍Kruskal,求出每种权值的边的使用数量num 再对于每种权值的边,2^num搜索出合法使 ...
- 最小生成树MST
定义 在一给定的无向联通带权图\(G = (V, E, W)\)中,\((u, v)\) 代表连接顶点 \(u\) 与顶点 \(v\) 的边,而 \(w(u, v)\) 代表此边的权重,若存在 \(T ...
- 最小生成树prim算法———模板
codevs.cn 最优布线问题 #include<cstdio>#include<cstring> bool u[101]; int g[101][101],minn[101 ...
随机推荐
- python编写工具及配置(notepad++)
学长跟我说老师实验室里用的ide是pycharm,我用了一天,整体还行,就是加载速度太慢,可是第二天用的时候就卡的想让人骂街,cpu占有率趋近100%,电脑配置不高,我寻思不能因为这个就马上换电脑吧, ...
- 解决gnuplot中'Terminal type set to 'unknown'不能显示绘图的问题
安装gnuplot: sudo apt-get install gnuplot 安装成功后,在终端输入gnuplot,进入gnuplot. 直接进行一个小测试: plot sin(x) 发现不能显示绘 ...
- Python学习之路——模块
一.模块: 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需 ...
- C# Programming Study #1
引用的时候需要在参数和使用的时候加上 ref 关键字 static bool addnum (ref int val) //引用 { ++val; return true; } 参数数组的概念,可以接 ...
- JS 随记
一.在内联框架中,刷新整个框架,在.net中使用此方法( ScriptManager.RegisterStartupScript(this.Page, this.GetType(), "re ...
- Spring Boot特性(转)
摘要: 1. SpringApplication SpringApplication 类是启动 Spring Boot 应用的入口类,你可以创建一个包含 main() 方法的类,来运行 SpringA ...
- java 利用java运行时的方法得到当前屏幕截图的方法(转)
将截屏图片保存到本地路径: package com.test; import java.awt.AWTException; import java.awt.Dimension; import java ...
- 图的BFS代码
图是严蔚敏书上P168的图, 图的邻接表存储,DFS可以看以前写的文章:http://www.cnblogs.com/youxin/archive/2012/07/28/2613362.html ]; ...
- 一个简单的基于canvas小游戏
GDOI2016是我的退役战,不知道是题目画风不对,还是我自身的问题. 不过没关系啦,反正已经进过一次队OI生涯就没有什么遗憾的了. 这几天尝试着去做了个所谓的html5小游戏,略显简陋,但还是写个总 ...
- hdu 4730 We Love MOE Girls
http://acm.hdu.edu.cn/showproblem.php?pid=4730 直接用string类处理字符串. AC代码: #include<iostream> #incl ...