图的应用--最小生成树

图的应用--最小生成树

生成树

概念:所有顶点均由边连接在一起.但不存在回路.

一个图可以有许多不同的生成树.

生成树特点:

  1. 生成树的顶点个数与图的顶点个数相同.
  2. 生成树是图的极小联通子图,去掉一条边则非联通
  3. 一个有n个顶点的连通图的生成树有n-1条边
  4. 在生成树中再加一条边必然形成回路
  5. 生成树中任意两个顶点间的路径是唯一的

还有n个顶带n-1条边的图不一定是生成树

image-20230707104426774

image-20230707104510979

无向图的生成树

使用dfs搜索找到的生成树.叫做深度优先生成树

使用bfs搜索找到的生成树,叫做广度优先生成树.

image-20230707105647844

最小生成树的定义

给定一个无向网络,在该网的所有生成树中,使得各边权值之和最小的那颗生成树成为该网的最小生成树,也叫最小代价生成树.

image-20230707110119351

典型用途

image-20230707110459675

构造最小生成树(MST)

image-20230710095606968

在生成树的构造过程中,图中n个顶点分属两个集合:

  1. 已落在生成树上的顶点集:U
  2. 尚未落在生成树上的顶点集:V-U
  3. 接下来则应在所有连通U中顶点和V-U中顶点的边中选取权值最小的边.

image-20230710100118173

方法1:Prim算法

image-20230710101214576

方法2:Kruskal算法

直接了当的贪心,但是不能形成环.

最小生成树可能不唯一

image-20230710101834607

两种算法的比较

image-20230710102209926

P3366 【模板】最小生成树

使用并查集来构建Kruskal算法

image-20230710112056919

#include <bits/stdc++.h>
#define yes cout<<"YES"<<'\n'
#define no 	cout<<"NO"<<'\n'

using namespace std;
typedef pair<int, int> PII;
const int N = 200008;

struct Node {
	int x, y, v;
} a[N];
int fa[50008], n, m;
bool cmp(Node a, Node b) {//自定义排序按照边权的大小进行排序
	return a.v < b.v;

}
int findset(int x) {//并查集的findset
	if (fa[x] == x) {
		return x;
	}
	int y = findset(fa[x]);
	fa[x] = y; //路径压缩
	return fa[x];
}
void Kruskal() {
	for (int i = 1; i <= n; i++) {
		fa[i] = i; //并查集初始化
	}
	sort(a + 1, a + m + 1, cmp);//排序
	int ans = 0;//记录答案
	int cnt = n;//现在有几个连通块,初始化的时候有n个
	for (int i = 1; i <= m; i++) {
		int x = findset(a[i].x);
		int y = findset(a[i].y);
		if (x != y) {//如果a[i].x和a[i].y不在一个集合里面的话
			fa[x] = y;//合并两个集合
			ans += a[i].v;//将边权加入到里面
			cnt--;//连通块的数量减1
		}
		if (cnt == 1) {//如果cnt为1就退出循环
			break;
		}
	}
	if (cnt == 1) {//打印结果
		cout << ans << '\n';
	} else {
		cout << "orz" << '\n';
	}

}
int main () {

	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		cin >> a[i].x >> a[i].y >> a[i].v;
	}
	Kruskal();


	return 0;
}

P1546 [USACO3.1] 最短网络 Agri-Net

posted @   harper886  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示