【洛谷 P8655】[蓝桥杯 2017 国 B] 发现环 题解(邻接表+并查集+路径压缩)

[蓝桥杯 2017 国 B] 发现环

题目描述

小明的实验室有 N N N 台电脑,编号 1 ∼ N 1 \sim N 1N。原本这 N N N 台电脑之间有 N − 1 N-1 N1 条数据链接相连,恰好构成一个树形网络。在树形网络上,任意两台电脑之间有唯一的路径相连。

不过在最近一次维护网络时,管理员误操作使得某两台电脑之间增加了一条数据链接,于是网络中出现了环路。环路上的电脑由于两两之间不再是只有一条路径,使得这些电脑上的数据传输出现了 BUG。

为了恢复正常传输。小明需要找到所有在环路上的电脑,你能帮助他吗?

输入格式

第一行包含一个整数 N N N

以下 N N N 行每行两个整数 a a a b b b,表示 a a a b b b 之间有一条数据链接相连。

输入保证合法。

输出格式

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

样例 #1

样例输入 #1

5
1 2
3 1
2 4
2 5
5 3

样例输出 #1

1 2 3 5

提示

对于 30 % 30\% 30% 的数据, 1 ≤ N ≤ 1000 1 \le N \le 1000 1N1000

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 1 0 5 1 \le N \le 10^5 1N105 1 ≤ a , b ≤ N 1 \le a,b \le N 1a,bN

时限 1 秒, 256M。蓝桥杯 2017 年第八届国赛


思路

首先,从输入中读取电脑的数量 N N N。接着,进行并查集的初始化,使得每个电脑都是其自身的根节点,这是通过 init() 函数实现的。

然后进入一个循环,循环次数为电脑的数量,即 N N N 次。在每次循环中,分别读取两个电脑的编号 u u u v v v。这两个编号表示电脑 u u u v v v 之间有一条数据链接。

对于每一对电脑 u u u v v v,首先检查它们是否在同一个集合中。这是通过 check(u, v) 实现的,如果它们的根节点相同,返回 1;否则,返回 0

如果 check(u, v) 返回 0,说明电脑 u u u v v v 之间还没有路径,可以添加一条连接。此时,通过 merge(u, v) 将它们合并到同一个集合中,这是通过找到它们的根节点,然后将一个的根节点的父节点设置为另一个的根节点实现的。同时,通过 add(u, v) 在图中添加一条连接,这是通过在邻接表中分别为 u u u v v v 添加对方的编号实现的。

如果 check(u, v) 返回 1,说明电脑 u u u v v v 已经通过其他路径连接,再添加一条连接就会形成环。此时,需要找出环中的所有电脑。首先,重置 bitset<N> vis,这是一个位集,用于标记电脑是否被访问过。然后,设置环的目标节点 dest = v,这是因为电脑 v v v 是形成环的那一条边的一个节点。最后,从电脑 u u u 开始进行深度优先搜索(DFS),找出所有在环中的电脑。这是通过 dfs(u, 0) 实现的,其中 0 是电脑 u u u 的父节点编号,因为 u u u 是DFS的起点,所以其父节点编号为 0

在深度优先搜索的过程中,首先标记当前电脑已被访问,这是通过 vis[x] = 1 实现的。然后,检查当前电脑是否是环的目标电脑,如果是,打印出所有已被访问的电脑(也就是环中的电脑),然后返回。如果不是,对当前电脑的所有邻居进行深度优先搜索,这是通过递归调用 dfs(i, x) 实现的,其中 i 是邻居的编号,x 是当前电脑的编号。最后,在DFS返回前,将当前电脑标记为未被访问,这是通过 vis[x] = 0 实现的。


AC代码

#include <algorithm>
#include <bitset>
#include <cmath>
#include <iostream>
#include <stack>
#include <vector>
#define AUTHOR "HEX9CF"
using namespace std;
using ll = long long;const int N = 1e6 + 7;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;int n;
int pre[N];
vector<int> g[N];
stack<int> stk;
bitset<N> vis;
int dest;int root(int a) {int i = a;while (i != pre[i]) {i = pre[i];}return (pre[a] = i);
}void merge(int a, int b) {int ra, rb;ra = root(a);rb = root(b);if (ra == rb) {return;}pre[ra] = rb;
}bool check(int a, int b) {int ra, rb;ra = root(a);rb = root(b);if (ra == rb) {return 1;}return 0;
}void add(int u, int v) {g[u].push_back(v);g[v].push_back(u);
}void init() {for (int i = 1; i <= n; i++) {pre[i] = i;}
}void dfs(int x, int fa) {// cout << x << endl;vis[x] = 1;if (x == dest) {for (int i = 1; i <= n; i++) {if (vis[i]) {cout << i << " ";}}cout << "\n";return;}for (const auto i : g[x]) {if (i == fa) {continue;}dfs(i, x);}vis[x] = 0;
}int main() {ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin >> n;init();for (int i = 1; i <= n; i++) {int u, v;cin >> u >> v;if (check(u, v)) {vis.reset();dest = v;dfs(u, 0);} else {merge(u, v);add(u, v);}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/593802.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拓扑排序--有向无环图中一个节点的所有祖先

题目描述 给你一个正整数 n &#xff0c;它表示一个 有向无环图 中节点的数目&#xff0c;节点编号为 0 到 n - 1 &#xff08;包括两者&#xff09;。 给你一个二维整数数组 edges &#xff0c;其中 edges[i] [fromi, toi] 表示图中一条从 fromi 到 toi 的单向边。 请你返…

OAuth 2.0 的四种方式

RFC 6749 OAuth 2.0 的标准是 RFC 6749 文件。该文件先解释了 OAuth 是什么。 OAuth 引入了一个授权层&#xff0c;用来分离两种不同的角色&#xff1a;客户端和资源所有者。…资源所有者同意以后&#xff0c;资源服务器可以向客户端颁发令牌。客户端通过令牌&#xff0c;去请…

K8S - Deployment 的版本回滚

当前状态 先看deployment rootk8s-master:~# kubectl get deploy -o wide --show-labels NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES …

Xen Server 8 Install

Xen Sevrer 前言 XenServer&#xff08;以前称为 Citrix Hypervisor&#xff09;是业界领先的平台&#xff0c;实现了经济高效的桌面、服务器和云虚拟化基础结构。XenServer 支持任意规模或类型的组织整合计算资源&#xff0c;以及将计算资源转换为虚拟工作负载&#xff0c;从…

代码随想录|Day32|动态规划01|509.斐波那契数列、70.爬楼梯、746.使用最小花费爬楼梯

509.斐波那契数列 动规五步曲&#xff1a; 确定 dp[i] 含义&#xff1a;第 i 个斐波那契数值为 dp[i]递推公式&#xff1a;dp[i] dp[i - 1] dp[i - 2]dp数组初始化&#xff1a;dp[0] dp[1] 1遍历顺序&#xff1a;从前向后打印dp数组 class Solution:def fib(self, n: int) …

【拓扑空间】示例及详解2

设A是X的一个子集&#xff0c; 内点、邻域&#xff1a;&#xff0c;则x是A的一个内点&#xff0c;A是x的一个领域 内部&#xff1a;A的所有的内点的集合称为A的内部&#xff0c;记 例1 证明&#xff1a; Proof: 例2 证明&#xff1a;是包含在A中的所有开集的并集&#xff0c…

Waifu2x:使用深度卷积神经网络的动漫风格艺术的图像超分辨率

Github网址&#xff1a;nagadomi/waifu2x&#xff1a;动漫风格艺术的图像超分辨率 (github.com) 该项目主要讲述的是如何利用预训练的深度学习模型来达到无损扩大收缩和去噪&#xff0c;对于一般训练图像的小伙伴应该很清晰图像经常要通过resize操作固定大小&#xff0c;然后c…

spring事务那些事

实际工作中还会面临千奇百怪的问题&#xff0c;看下面返个例子&#xff08;注意MySql数据库测试&#xff09;&#xff1a; //1.hello1Service 调用 hello2Service Transactional(propagation Propagation.REQUIRED,rollbackFor Exception.class) public void doUpdate() {//…

【代码随想录】链表

203. 移除链表元素 // public class ListNode { // int val; // ListNode next; // ListNode() {} // ListNode(int val) { this.val val; } // ListNode(int val, ListNode next) { this.val val; this.next next;} // }class Solution {public ListNo…

Linux 安装系统可视化监控工具 Netdata

目录 About 监控工具 NetdataLinux 系统安装 Netdata关于 openEuler1、查看内核信息2、查看主机信息3、查看 dnf 包管理器的版本 Netdata 安装1、更新系统环境相关 rpm 包2、查看 netdata 包信息3、安装 netdata 包4、编辑 netdata.conf 配置5、启动 netdata 服务6、查看 netda…

TCP的十个重要的机制

注&#xff1a;TCP不是只有十个机制 TCP 可靠传输是tcp最为重要的核心&#xff08;初心&#xff09; 可靠传输&#xff0c;并不是发送方把数据能够100%的传输给接收方 而是退而求其次 让发送方发送出去数据之后&#xff0c;能够知道接收方是否收到数据。 一但发现对方没有…

FAS-Net

感想 图的下标弄不好&#xff0c;且作者未提供代码。AAAI的质量也就这样吧