蓝桥杯真题—发现环(并查集+DFS)

题目描述

小明的实验室有N台电脑,编号1~N。原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。
不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了BUG。
为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?

输入描述

输入范围:
第一行包含一个整数 N 。
以下 N 行每行两个整数 a,b,表示 a 和 b 之间有一条数据链接相连。
其中,对于30%的数据,1 <= N <= 1000,对于100%的数据, 1 <= N <= 100000, 1 <= a, b <= N。
输入保证合法。

输出描述

按从小到大的顺序输出在环路上的电脑的编号,中间由一个空格分隔。

解题思路

用并查集找到环路上的一点,从这个点开始dfs,若过程中找到原点则回溯并记录经过的点。

代码

n = int(input())
f = [i for i in range(n+1)]
g = 
### 蓝桥杯竞赛中的并查集应用 #### 题目描述 在一个由多个房间组成的建筑中,每个房间里有一盏灯。给定一些开关操作,这些操作可以改变某些房间内灯光的状态(开/关),目标是通过一系列合法的操作使得所有指定的房间内的灯都处于开启状态。 为了验证某个特定配置下的解决方案是否有效,可以把每条灯管当作一个节点,对其进行编号,并建立相应的图结构来表示各个灯之间的关系[^2]。接着利用深度优先搜索(DFS)遍历所有可能的状态组合,在此过程中采用并查集数据结构检查当前状态下被点亮的灯是否属于同一组。 当执行一次成功的开关动作后,如果两盏原本不在一起的灯现在应该相连,则需调用`union(x, y)`函数将它们所在的两个独立子树合并成一个新的更大的连通分支;反之亦然,若要断开连接则应保持各自所属的不同集合不变。最终目的是让所有的目标灯具位于同一个根节点之下,即形成了所谓的“超级父”。 #### Python 实现示例 ```python class UnionFind: def __init__(self, n): self.parent = list(range(n)) def find(self, p): while p != self.parent[p]: self.parent[p] = self.parent[self.parent[p]] # Path compression p = self.parent[p] return p def union(self, p, q): rootP = self.find(p) rootQ = self.find(q) if rootP == rootQ: return self.parent[rootP] = rootQ def solve_lights_problem(lights_status, operations): uf = UnionFind(len(lights_status)) for op in operations: light_a, light_b = map(int, op.split()) uf.union(light_a - 1, light_b - 1) target_set_id = None all_on = True for i, status in enumerate(lights_status): set_id = uf.find(i) if not status and (target_set_id is None or set_id == target_set_id): target_set_id = set_id continue elif not status and set_id != target_set_id: all_on = False break return "YES" if all_on else "NO" ``` 上述代码定义了一个简单的并查集类 `UnionFind` 来管理不同灯泡间的归属情况,并实现了基本的功能如查找(`find`) 和联合 (`union`). 函数`solve_lights_problem()` 接收初始时各房间灯的状态列表以及一系列指示如何调整相邻房间之间联系的动作序列作为输入参数,最后返回能否使所有期望位置上的灯都被打开的结果字符串 `"YES"` 或者 `"NO"`.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我恨TLE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值