题目链接:https://www.luogu.org/problem/P3366

最小生成树模板题。

Kruskal算法

算法思想:给边按边权从小到大排序,然后遍历每一条边,如果边上的两个点不在同一个集合,则选择这条边,并将两个点所在集合合并。直到选择了 \(n-1\) 条边。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 200200;
int n, m, f[5050], cnt, u[maxn], v[maxn], idx[maxn];
long long ans, w[maxn];
void init() {
for (int i = 1; i <= n; i ++) f[i] = i;
}
int func_find(int x) {
return x == f[x] ? x : f[x] = func_find(f[x]);
}
void func_union(int x, int y) {
int a = func_find(x), b = func_find(y);
f[a] = f[b] = f[x] = f[y] = min(a, b);
}
bool cmp(int i, int j) { return w[i] < w[j]; }
int main() {
cin >> n >> m;
init();
for (int i = 0; i < m; i ++) {
cin >> u[i] >> v[i] >> w[i];
idx[i] = i;
}
sort(idx, idx+m, cmp);
for (int k = 0; k < m; k ++) {
int i = idx[k];
if (func_find(u[i]) != func_find(v[i])) {
func_union(u[i], v[i]);
cnt ++;
ans += w[i];
if (cnt == n-1) break;
}
}
if (cnt < n-1) puts("orz");
cout << ans << endl;
return 0;
}

Prim算法

算法思想:设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到V中任意一点的权值最小,此时将b点也加入集合V;以此类推,现在的集合V={a,b},再从集合U-V中找到另一点c使得点c到V中任意一点的权值最小,此时将c点加入集合V,直至所有顶点全部被加入V,此时就构建出了一颗MST。因为有N个顶点,所以该MST就有N-1条边,每一次向集合V中加入一个点,就意味着找到一条MST的边。

实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5050;
#define INF (1<<29)
int n, m, dis[maxn];
bool vis[maxn];
struct Node {
int v, w;
Node () {}
Node (int _v, int _w) { v = _v; w = _w; }
};
vector<Node> g[maxn];
void prim() {
int ans = 0;
dis[1] = 0;
for (int i = 2; i <= n; i ++) dis[i] = INF;
for (int i = 0; i < n; i ++) {
int id = 0;
for (int j = 1; j <= n; j ++) if (!vis[j] && (!id || dis[j] < dis[id])) id = j;
if (!id || dis[id] == INF) {
puts("orz");
return;
}
ans += dis[id];
vis[id] = true;
int sz = g[id].size();
for (int j = 0; j < sz; j ++) {
int v = g[id][j].v, w = g[id][j].w;
if (vis[v]) continue;
if (dis[v] > w) dis[v] = w;
}
}
cout << ans << endl;
}
int main() {
cin >> n >> m;
while (m --) {
int u, v, w;
cin >> u >> v >> w;
g[u].push_back(Node(v, w));
g[v].push_back(Node(u, w));
}
prim();
return 0;
}

洛谷P3366 【模板】最小生成树 题解的更多相关文章

  1. [洛谷P3366] [模板] 最小生成树

    存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...

  2. 最小生成树 & 洛谷P3366【模板】最小生成树 & 洛谷P2820 局域网

    嗯... 理解生成树的概念: 在一幅图中将所有n个点连接起来的n-1条边所形成的树. 最小生成树: 边权之和最小的生成树. 最小瓶颈生成树: 对于带权图,最大权值最小的生成树. 如何操作? 1.Pri ...

  3. 洛谷P3366【模板】最小生成树-克鲁斯卡尔Kruskal算法详解附赠习题

    链接 题目描述 如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz 输入输出格式 输入格式: 第一行包含两个整数N.M,表示该图共有N个结点和M条无向边.(N<=5000,M&l ...

  4. 洛谷P2832 行路难 分析+题解代码【玄学最短路】

    洛谷P2832 行路难 分析+题解代码[玄学最短路] 题目背景: 小X来到了山区,领略山林之乐.在他乐以忘忧之时,他突然发现,开学迫在眉睫 题目描述: 山区有n座山.山之间有m条羊肠小道,每条连接两座 ...

  5. 【洛谷P3960】列队题解

    [洛谷P3960]列队题解 题目链接 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有 n×m ...

  6. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  7. 洛谷P2312 解方程题解

    洛谷P2312 解方程题解 题目描述 已知多项式方程: \[a_0+a_1x+a_2x^2+\cdots+a_nx^n=0\] 求这个方程在 \([1,m]\) 内的整数解(\(n\) 和 \(m\) ...

  8. 洛谷P1577 切绳子题解

    洛谷P1577 切绳子题解 题目描述 有N条绳子,它们的长度分别为Li.如果从它们中切割出K条长度相同的 绳子,这K条绳子每条最长能有多长?答案保留到小数点后2位(直接舍掉2为后的小数). 输入输出格 ...

  9. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  10. 洛谷 P1220 关路灯 题解

    Description 有 $n$ 盏路灯,每盏路灯有坐标(单位 $m$)和功率(单位 $J$).从第 $c$ 盏路灯开始,可以向左或向右关闭路灯.速度是 $1m/s$.求所有路灯的最少耗电.输入保证 ...

随机推荐

  1. Hdu 1299

    Diophantus of Alexandria Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  2. Excel柱状图折线图组合怎么做 Excel百分比趋势图制作教程

    Excel柱状图折线图组合怎么做 Excel百分比趋势图制作教程 用excel作图时候经常会碰到做柱状图和折线图组合,这样的图一般难在折线图的数据很小,是百分比趋势图,所以经常相对前面主数据太小了,在 ...

  3. Oracle企业管理框架

    oracle管理服务器 是一个基于java的web构件,该构件是dba用来监视和控制oracle企业框架内各个受管理目标的实际界面 oracle储存库 已收集到并与受管理目标有关的配置和监视信息被存储 ...

  4. JavaScript--返回顶部方法:锚链接、行内式js写法、外链式、内嵌式

    返回网页顶部方法 一.锚链接 simpleDemo: <!DOCTYPE html> <html lang="en"> <head> <m ...

  5. iOS 9 学习系列:UIStack View

    http://www.cocoachina.com/ios/20150921/13492.html 在 iOS9 中,Apple 引入了 UIStackView,他让你的应用可以通过简单的方式,纵向或 ...

  6. BZOJ4241历史研究题解

    题目连接 很显然可以想到分块,用f[i][j]表示块i到块j的ans,然后发现答案一定是f[i][j] 或者其他在边角出现的数字 我们在记下g[i][j]从开头到块i中的数字j出现的次数 这样就每一次 ...

  7. vagrant up提示"Couldn't open file /path/to/base"的错误解决方法

    在vagrant使用命令vagrant up启动虚拟机时 出错: C:\Vagrant>vagrant up Bringing machine 'default' up with 'virtua ...

  8. Python发送邮件1(带附件的)

    普通的发邮件(不使用类)

  9. List容器-LinkedList链表

    LinkedList--链表 特点: 删除,增加 用LinkedList性能高  层次查找不适合       查询用ArrayList  数组下标查找  插入和删除慢缺点是要做移位操作 总结:Link ...

  10. git操作——TortoiseGit指定某个分支clone

    需求 需要使用TortoiseGit 克隆某个项目分支 操作 勾选分支,输入分支名称clone代码即可