C++图论基础最小生成树经典OJ题流食般投喂

本篇标红的字段均是可以升级的经验条呦~


OJ题来源:洛谷

OJ题名:买礼物

OJ题归属:图论基础【最小生成树】

解题算法:kruskal算法(kk算法)

经验总结:用kurskal算法构造出来的生成树可能有若干个,顶点有不连通的情况不影响他建树,比如:a-a a-a a-a

|

a-a

kruskal算法的关键变量cnt与节点n是有关系的,cnt变量记录选的条数,n是节点个数,n - cnt 的差值就是构建出生成树的具体个数。

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 500 * 500 + 10;

int pos;
int a, n;
int fa[N]; // 并查集
struct node
{
	int x, y, z;
}e[N];
int ret, cnt;

int find(int x)
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

bool cmp(node& a, node& b)
{
	return a.z < b.z;
}

void kk()
{
	sort(e + 1, e + 1 + pos, cmp);

	for (int i = 1; i <= pos; i++)
	{
		int x = e[i].x, y = e[i].y, z = e[i].z;

		int fx = find(x), fy = find(y);
		if (fx != fy)
		{
			cnt++;
			ret += z;
			fa[fx] = fy;
		}
	}
}

int main()
{
	cin >> a >> n;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			int k; cin >> k;
			if (i >= j || k > a || k == 0) continue;
			pos++;
			e[pos].x = i, e[pos].y = j, e[pos].z = k;
		}
	}

	// 并查集初始化
	for (int i = 1; i <= n; i++) fa[i] = i;

	kk(); // 求得ret/cnt

	cout << ret + (n - cnt) * a << endl;

	return 0;
}

OJ题来源:洛谷

OJ题名:繁忙的都市

OJ题归属:图论基础【最小生成树】

解题算法:kruskal算法(kk算法)

此题有三个限制条件,前两个条件翻译出来是要求是一棵生成树,最后一个翻译出来是要是一颗瓶颈生成树。

经验总结:

瓶颈生成树的概念:在所有生成树中,最大边权值最小的生成树。

瓶颈生成树的定理:最小生成树就是瓶颈生成树。

|-------|-------------------------|
| 最小生成树 | ret维护的是边权和最小 |
| 瓶颈生成树 | ret维护的是 n - 1 条边中,边权最大值 |

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 310, M = 8010;

int n, m;
struct node
{
	int x, y, z;
}a[M];
int fa[N]; // 并查集维护已选的顶点

int find(int x)
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

int ret; // 维护 n - 1 条边中,边权最大值

bool cmp(node& a, node& b)
{
	return a.z < b.z;
}

void kk()
{
	sort(a + 1, a + 1 + m, cmp);

	for (int i = 1; i <= m; i++)
	{
		int x = a[i].x, y = a[i].y, z = a[i].z;

		int fx = find(x), fy = find(y);
		if (fx != fy)
		{
			ret = max(ret, z);
			fa[fx] = fy;
		}
	}
}

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

	// 并查集初始化
	for (int i = 1; i <= n; i++) fa[i] = i;

	cout << n - 1 << " ";

	kk();

	cout << ret << endl;

	return 0;
}

OJ题来源:洛谷

OJ题名:滑雪

OJ题归属:图论基础【最小生成树】

解题算法:dfs + kruskal算法(kk算法)

经验总结:最小生成树在概念上是针对于无向图的,但是,这题向我们表明,特殊情景下的有向图也是适用的,这题的图是一个有向图,但是题中提到的时间胶囊的概念,其实功能就是回溯,是的,这样我们就可以把这个有向图可以看成可以递归的二叉树。此题的各个顶点之间不确定是不是连通的,所以不是所有的边都需要记录,我们只记录由1这个节点递归过程中可以经历的边,对这些边进行排序、选边操作。此题kk算法的排序有改变,滑雪滑雪,排序的第一关键字就是高度,由高到低,高度一致时,在按边权由小到大排序。

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 1e5 + 10, M = 2e6 + 10;

int n, m;
int h[N]; // 存该景点高度
vector<PII> a[N]; // 存图
int fa[N]; // 并查集
int pos; // 在选择范围内的边数
struct node
{
	int x, y, z;
}e[M]; // 存储在选择范围内的边
LL cnt, ret; // 景点数 路径和
bool st[N];

int find(int x)
{
	return fa[x] == x ? x : fa[x] = find(fa[x]);
}

void dfs(int u)
{
	cnt++;
	st[u] = true;

	for (auto& p : a[u])
	{
        // 存储在选择范围内的边
		int y = p.first, z = p.second;
		pos++;
		e[pos].x = u, e[pos].y = y, e[pos].z = z;

		if (!st[y]) dfs(y);
	}
}

bool cmp(node& a, node& b)
{
	int ay = a.y, by = b.y;
	
    // 排序第一关键字:高度,第二关键字:边权
	if (h[ay] != h[by]) return h[ay] > h[by];
	else return a.z < b.z;
}

void kk()
{
	sort(e + 1, e + 1 + m, cmp);

	// 选边
	for (int i = 1; i <= pos; i++)
	{
		int x = e[i].x, y = e[i].y, z = e[i].z;
		int fx = find(x), fy = find(y);
		if (fx != fy)
		{
			ret += z;
			fa[fx] = fy;
		}
	}
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i++) cin >> h[i];
	for (int i = 1; i <= m; i++)
	{
		int x, y, z; cin >> x >> y >> z;

		//判断哪些边可以存
		if (h[x] >= h[y]) a[x].push_back({ y, z });
		if (h[y] >= h[x]) a[y].push_back({ x, z });
	}

	// 并查集初始化
	for (int i = 1; i <= n; i++) fa[i] = i;

	dfs(1);
	cout << cnt << " ";

	kk();
	cout << ret << endl;

	return 0;
}

感谢~

相关推荐
无限进步_1 小时前
【Linux】进程状态、僵尸与孤儿、进程调度
linux·运维·服务器·开发语言·数据结构·算法
郝学胜-神的一滴1 小时前
力扣 662 :二叉树最大宽度
java·数据结构·c++·python·算法·leetcode·职场和发展
仙俊红1 小时前
反射到底解决什么问题?
java·开发语言
2301_764441331 小时前
基于Stackelberg博弈的分散式库存模型
python·算法·数学建模
大阳1231 小时前
ARM.9(RGBLCD,PWM)
c语言·开发语言·汇编·单片机·嵌入式硬件·pwm·rgblcd
searchforAI1 小时前
培训视频转文字后怎么做团队复盘?把本地视频整理成AI笔记的实操方案
人工智能·笔记·ai·whisper·音视频·语音识别·腾讯会议
鲁子狄2 小时前
lrnev:让 AI 协作开发「有记忆、可追溯」的项目治理引擎 | 零模型依赖,文件即真相
人工智能·笔记·gpt·ai·ai编程
加油码2 小时前
Linux IO 多路转接详解:从 select、poll 到 epoll
linux·c++
qq 13740186112 小时前
医用无菌屏障系统加速老化标准解读:ASTM F1980-2016 全解析
人工智能·算法·加速老化·包装测试·astm·医疗器械包装·无菌屏障系统
wayz112 小时前
Overlap:SLOPE(线性回归斜率)技术指标详解
算法·金融·数据分析·回归·线性回归·量化交易·特征工程