[LGOJ2245]星际导航——[kruskal重构树+LCA]

本文深入探讨了Kruskal重构树算法,这是一种在图论中用于寻找最小生成树的有效方法。通过将边上的端点与虚点连接,转换为点权,重构树能够高效地解决特定类型的路径问题。文章提供了详细的算法实现代码,包括如何构建重构树,以及如何利用重构树上的最低公共祖先(LCA)来确定路径上最大边权的最小值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
【题意分析】

知识点:kruskal重构树

构建重构树的过程:kruskal时,将边上的端点全都和一个虚点相连,这个点的点权就是原来的边权。

性质:重构树上的LCA就是两边所有路径危险值最大的最小值。

Code:

//KajKeusaka
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#define MAXN 300000
using namespace std;

struct fls {int to, next;} edge[MAXN << 1];
struct Node {int x, y, v;} data[MAXN];

int top[MAXN], head[MAXN << 1], f[MAXN], father[MAXN], depth[MAXN];
int size[MAXN], son[MAXN], val[MAXN], n, m, cnt, Cnt;

inline int read () {
	register int s = 0, w = 1;
	register char ch = getchar ();
	while (! isdigit (ch)) {if (ch == '-') w = -1; ch = getchar ();}
	while (isdigit (ch)) {s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar ();}
	return s * w;
}

int getfather (int x) {return (x == f[x]) ? x : f[x] = getfather (f[x]);}
inline void connect2 (int u, int v) {edge[++Cnt].to = v, edge[Cnt].next = head[u], head[u] = Cnt;}
inline bool cmp (Node a, Node b) {return a.v < b.v;}

inline int LCA (int x, int y) {
	while (top[x] != top[y]) {
		if (depth[top[x]] < depth[top[y]]) swap (x, y);
		x = father[top[x]];
	}
	return (depth[x] > depth[y]) ? y : x;
}

void DFS1 (int now, int fa, int d) {
	depth[now] = d, father[now] = fa, size[now] = 1; int maxson = -1;
	for (register int i = head[now]; i; i = edge[i].next) {
		int v = edge[i].to; if (v == fa) continue;
		DFS1 (v, now, d + 1), size[now] += size[v];
		if (size[v] > maxson) {son[now] = v, maxson = size[v];}
	}
}

void DFS2 (int now, int top_heavy) {
	top[now] = top_heavy; if (! son[now]) return;
	DFS2 (son[now], top_heavy);
	for (register int i = head[now]; i; i = edge[i].next) {
		int v = edge[i].to;
		if (v != father[now] && v != son[now]) DFS2 (v, v);
	}
}

int main () {
	n = read (), m = read ();
	for (register int i = 1; i <= m; i++)
		data[i].x = read (), data[i].y = read (), data[i].v = read ();
	sort (data + 1, data + m + 1, cmp); int now = n;
	for (register int i = 1; i <= n * 2; i++) f[i] = i;
	for (register int i = 1; i <= m; i++) {
		int x = data[i].x, y = data[i].y;
		int xx = getfather (x), yy = getfather (y);
		if (xx != yy) {
			f[xx] = f[yy] = ++now;
			connect2 (xx, now), connect2 (now, xx),
			connect2 (yy, now), connect2 (now, yy);
			val[now] = data[i].v;
		}
	}
	for (register int i = now; i; i--)
		if (! depth[i]) DFS1 (i, 0, 1), DFS2 (i, i);
	int q = read ();
	for (register int I = 1; I <= q; I++) {
		int u = read (), v = read ();
		if (getfather (u) != getfather (v)) puts ("impossible");
		else printf ("%d\n", val[LCA (u, v)]);
	}
	return 0;
}
/*
4 5
1 2 5
1 3 2
2 3 11
2 4 6
3 4 4
3
2 3
1 4
1 2
*/
内容概要:本文详细解析了2014年全国大学生电子设计竞赛C题——智能小车设计的全过程。文章首先介绍了该竞赛的背景及其重要意义,指出其不仅是对学生电子设计能力的考验,还对学生的学术成长和职业发展有深远影响。随后,文章深入剖析了C题的具体要求,包括小车的起跑、行驶、超车等复杂动作,强调了硬件(如控制模块、电源模块、车体、电机模块)和软件(如信号检测与控制、两车通信、节能技术、程序设计)方面的关键技术和实现方法。最后,文章分享了测试与优化的经验,并总结了团队合作、知识储备和实践能力的重要性,展望了电子设计领域的发展趋势。 适合人群:电子信息类专业学生、电子设计爱好者及希望深入了解智能小车设计的技术人员。 使用场景及目标:①了解全国大学生电子设计竞赛的背景和重要性;②掌握智能小车设计的硬件选型和软件编程技巧;③学习信号检测与控制、两车通信、节能技术等关键技术;④借鉴测试与优化的经验,提升实际动手能力和解决问题的能力。 阅读建议:本文内容详实,涵盖了从理论到实践的各个方面。建议读者在阅读过程中结合实际操作,逐步理解和掌握智能小车设计的各项技术和原理,特别是对硬件电路设计和软件编程部分,可以通过搭建实验平台进行实践,加深理解。同时,关注文中提到的测试与优化策略,有助于提高实际项目的成功率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值