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

news2025/1/20 10:49:41

[蓝桥杯 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.coloradmin.cn/o/1571773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设计模式总结-外观模式(门面模式)

外观模式 模式动机模式定义模式结构外观模式实例与解析实例一&#xff1a;电源总开关实例二&#xff1a;文件加密 模式动机 引入外观角色之后&#xff0c;用户只需要直接与外观角色交互&#xff0c;用户与子系统之间的复杂关系由外观角色来实现&#xff0c;从而降低了系统的耦…

【Canvas技法】用椭圆绘制经纬线

【图示】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>用椭圆绘制经纬线</title><style type"text/css"…

二叉树算法练习day.2

102.二叉树的层序遍历 链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&a…

Peter算法小课堂—树状数组

大家好&#xff0c;我是人见人爱&#xff0c;花见花开&#xff0c;车见车爆胎的树状数组Peter Pan&#xff0c;hhh 讲正文前&#xff0c;先来一个长文警告⚠很重要的知识点&#xff1a;L SB&#xff08;SB&#xff1f;&#xff09; LSB 怎么算呢&#xff1f; 哦……懂了&…

班级事务管理系统设计与实现(论文+源码)_kaic

摘 要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&#xff0c;对班级事务信息管理的提升&#…

在flutter中添加video_player【视频播放插件】

添加插件依赖 dependencies:video_player: ^2.8.3插件的用途 在Flutter框架中&#xff0c;video_player 插件是一个专门用于播放视频的插件。它允许开发者在Flutter应用中嵌入视频播放器&#xff0c;并提供了一系列功能来控制和定制视频播放体验。这个插件对于需要在应用中展…

Linux| Awk 中“next”命令奇用

简介 本文[1]介绍了在Linux中使用Awk的next命令来跳过剩余的模式和表达式&#xff0c;读取下一行输入的方法。 next命令 在 Awk 系列教程中&#xff0c;本文要讲解如何使用 next 命令。这个命令能让 Awk 跳过所有你已经设置的其他模式和表达式&#xff0c;直接读取下一行数据。…

LeetCode-54. 螺旋矩阵【数组 矩阵 模拟】

LeetCode-54. 螺旋矩阵【数组 矩阵 模拟】 题目描述&#xff1a;解题思路一&#xff1a;定义上下左右四个边界&#xff0c;进行模拟。解题思路二&#xff1a;5行 Python zip函数图一乐解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个 m 行 n 列的矩阵 matrix &#xf…

005 文本属性 字体属性

文章目录 文本属性text-decoration(重要)text-transformtext-indenttext-align(重要)letter-spacing、word-spacing 字体属性font-size(重要)font-family(重要)font-weight(重要)font-stylefont-variantline-height(常用)font 文本属性 text-decoration(重要) 用于设置文字的…

Redis主从集群-主从复制(通俗易懂)

为什么要搭建主从集群&#xff1f; 单节点Redis的并发能力是有上限的&#xff0c;要进一步提高Redis的并发能力&#xff0c;可以搭建主从集群&#xff0c;实现读写分离。一般都是一主多从&#xff0c;主节点负责写数据&#xff0c;从节点负责读数据&#xff0c;主节点写入数据…

python画带阴影折线图

&#xff08;1&#xff09; # codinggbk import matplotlib.pyplot as plt import numpy as np# 创建一些示例数据 x np.linspace(-3, 3, 60) y_mean np.sin(x) y_std np.sin(x)# 画折线图 b-:蓝色实线 plt.plot(x, y_mean, b-, labelMean)# 填充阴影表示标准差 alpha…

mysql中主键索引和联合索引的原理解析

mysql中主键索引和联合索引的原理解析 一、主键索引二、什么是联合索引? 对应的B树是如何生成的?1、建立索引方式2、什么是最左前缀原则?3、回表4、为什么要遵守最左前缀原则才能利用到索引?5、什么是覆盖索引?6、索引扫描底层原理7、order by为什么会导致索引消失&#x…

java -网络编程socket-聊天室-02

完整版代码 java -聊天室的代码: 用于存放聊天室的项目的代码和思路导图https://gitee.com/to-uphold-justice-for-others/java---code-for-chat-rooms.git 先引入线程的正统解释 线程&#xff08;Thread&#xff09;是程序执行流的最小单元。线程是操作系统分配CPU时间片的基…

(2024,超分辨率,膨胀卷积和低通滤波,SD)FouriScale:免训练高分辨率图像合成的频率视角

FouriScale: A Frequency Perspective on Training-Free High-Resolution Image Synthesis 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 相关工作 2.2 通过扩散模型进行…

DotNetBar的SlidePanel和metroTilePanel使用笔记

一、前言 界面组件DotNetBar2中的2个控件属性SlidePanel和metroTitlePanel的使用方法&#xff0c;网上相关资源较少&#xff0c;就一些属性的使用学习记录如下&#xff1a; SlideSideDevComponents.DotNetBar.Controls.eSlideSide.Top/Bottom/Right/Left 及 metroTilePanel和m…

蓝桥杯每日一题:公约数(gcd)

题目描述&#xff1a; 给定两个正整数 a 和 b。 你需要回答 q 个询问。 每个询问给定两个整数 l,r&#xff0c;你需要找到最大的整数 x&#xff0c;满足&#xff1a; x 是 a和 b 的公约数。l≤x≤r。 输入格式 第一行包含两个整数 a,b。 第二行包含一个整数 q。 接下来…

Python人工智能应用---中文分词词频统计

目录 1.中文分词 2.循环分别处理列表 &#xff08;1&#xff09;分析 &#xff08;2&#xff09;代码解决 3.词袋模型的构建 &#xff08;1&#xff09;分析需求 &#xff08;2&#xff09;处理分析 1.先实现字符串的连接 2.字符串放到新的列表里面 4.提取高频词语 &…

WordPress建站教程:10步快速搭建个人网站

WordPress是一个广泛使用的内容管理系统&#xff08;CMS&#xff09;&#xff0c;凭借其用户友好的界面和大量可定制的主题和插件&#xff0c;为WordPress 提供了多功能性和灵活性&#xff0c;可用于创建各种类型的网站&#xff0c;包括个人博客、B2B企业网站、B2C外贸网站等&a…

【HTML】CSS样式(二)

上一篇我们学习了CSS基本样式和选择器&#xff0c;相信大家对于样式的使用有了初步认知。 本篇我们继续来学习CSS中的扩展选择器及CSS继承性&#xff0c;如何使用这些扩展选择器更好的帮助我们美化页面。 下一篇我们将会学习CSS中常用的属性。 喜欢的 【点赞】【关注】【收藏】…

非关系型数据库(缓存数据库)redis的性能管理

目录 一.Redis性能管理 1.Info Memory——查看Redis内存使用 2.内存碎片率 3. 内存使用率 4.内存回收key 二.缓存的穿透&#xff0c;击穿和雪崩 1.缓存的穿透 1.1 问题描述 1.2 缓存穿透发生的条件 1.3 缓存穿透发生的原因 1.4 解决方案 2 缓存的击穿 2.1 问题描…