题干:

问题描述

  小明的实验室有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

  输入保证合法。

输出格式

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

样例输入

5
1 2
3 1
2 4
2 5
5 3

样例输出

1 2 3 5

解题报告:

法一:先并查集求出第一个 成环 的边,这条边的两个顶点一定是环中的顶点,以这两个点为起点进行dfs,找到环并记录,就可以了。

法二:tarjan。

法三:记录每个顶点的入度,用类似拓扑排序的方法处理所有顶点,如果最后queue内没有元素了的时候,剩下没有遍历到的元素都是环内元素,时间关系不再实现代码。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
vector<int> vv[MAX];
int f[MAX];
int ans[MAX];
int tar1,tar2,flag,tot;
int getf(int v) {return f[v] == v ? v : f[v] = getf(f[v]);
}
void merge(int u,int v) {int t1 = getf(u);int t2 = getf(v);f[t2]= t1;
}
void dfs(int cur,int rt,int step) {int up = vv[cur].size();if(flag) return ;ans[step] = cur;if(cur == tar2) {tot = step;flag = 1;return;}for(int i = 0; i<up; i++) {int v = vv[cur][i];if(v == rt) continue;dfs(v,cur,step+1);if(flag) return ;}}
int main()
{int n,fg=0;cin>>n;for(int i = 1; i<=n; i++) f[i] = i;for(int u,v,i = 1; i<=n; i++) {scanf("%d%d",&u,&v);vv[u].pb(v);vv[v].pb(u);if(getf(u) == getf(v)&&!fg) {tar1=u,tar2=v;fg=1;}merge(u,v);}dfs(tar1,tar2,1);sort(ans+1,ans+tot+1);for(int i = 1; i<=tot; i++) printf("%d%c",ans[i],i==tot?'\n':' ');return 0 ;
}

Tarjan写法:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
vector<int> vv[MAX];
int n,m;
int DFN[MAX],LOW[MAX],stk[MAX];
bool vis[MAX];
int f[MAX];
stack<int> sk;
int ans[MAX],fk;
int clk,index;
void tarjan(int x,int rt) {DFN[x] = LOW[x] = ++clk;vis[x] = 1;stk[++index] = x;int up = vv[x].size();for(int i = 0; i<up; i++) {int v = vv[x][i];if(v == rt) continue;if(!DFN[v]) {tarjan(v,x);LOW[x] = min(LOW[x],LOW[v]);} else{if(vis[v]) LOW[x] = min(LOW[x],DFN[v]);else printf("123123");} }if(DFN[x] == LOW[x]) {while(sk.size()) sk.pop();while(1) {int tmp = stk[index--];sk.push(tmp);vis[tmp]=0;if(tmp == x) break;}if(sk.size() > 1) {while(sk.size()) ans[++fk] = sk.top(),sk.pop();}}
}int main() {cin>>n;for(int i = 1; i<=n; i++) f[i]=i;for(int a,b,i = 1; i<=n; i++) {scanf("%d%d",&a,&b);vv[a].pb(b);vv[b].pb(a);}tarjan(1,-1);sort(ans+1,ans+fk+1);for(int i = 1; i<=fk; i++) printf("%d%c",ans[i],i == fk ? '\n' : ' ');return 0 ;
}

因为可以保证只有一个环,所以只会有一次机会更新ans数组。

【蓝桥杯官网试题 - 历届试题】发现环(dfs+并查集,或无向图tarjan判环,无向环,或拓扑排序)相关推荐

  1. 【蓝桥杯官网训练 - 历届试题】对局匹配(dp,思维,取模)

    题干: 问题描述 小明喜欢在一个围棋网站上找别人在线对弈.这个网站上所有注册用户都有一个积分,代表他的围棋水平. 小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起.如果 ...

  2. 蓝桥杯官网 试题 PREV-61 历届真题 装饰珠【第十一届】【决赛】【研究生组】【C++】【C】【Java】【Python】四种解法

    为帮助大家能在6月18日的比赛中有一个更好的成绩,我会将蓝桥杯官网上的历届决赛题目的四类语言题解都发出来.希望能对大家的成绩有所帮助. 今年的最大目标就是能为[一亿技术人]创造更高的价值. 资源限制 ...

  3. 蓝桥杯官网 试题 PREV-240 历届真题 答疑【第十一届】【决赛】【研究生组】【C++】【C】【Java】【Python】四种解法

    为帮助大家能在6月18日的比赛中有一个更好的成绩,我会将蓝桥杯官网上的历届决赛题目的四类语言题解都发出来.希望能对大家的成绩有所帮助. 今年的最大目标就是能为[一亿技术人]创造更高的价值. 资源限制 ...

  4. 蓝桥杯官网 试题 PREV-109 历届真题 扫地机器人【第十届】【省赛】【研究生组】【C++】【Java】【Python】三种解法

    为帮助大家能在6月18日的比赛中有一个更好的成绩,我会将蓝桥杯官网上的历届决赛题目的四类语言题解都发出来.希望能对大家的成绩有所帮助. 今年的最大目标就是能为[一亿技术人]创造更高的价值. 资源限制 ...

  5. 蓝桥杯官网 试题 PREV-265 历届真题 砝码称重【第十二届】【省赛】【研究生组】【C++】【C】【Java】【Python】四种解法

    为帮助大家能在6月18日的比赛中有一个更好的成绩,我会将蓝桥杯官网上的历届决赛题目的四类语言题解都发出来.希望能对大家的成绩有所帮助. 今年的最大目标就是能为[一亿技术人]创造更高的价值. 资源限制 ...

  6. 蓝桥杯官网刷题记录python

    蓝桥杯官网刷题记录python 由于很多题都会在2020.2021.2022年省赛出现,有的在前面文章里做过的这里就不会再说了 一.空间 小蓝准备用 256MB 的内存空间开一个数组,数组的每个元素都 ...

  7. 蓝桥杯python组练题第二天——成绩统计——蓝桥杯官网题库

    成绩统计 题目描述 小蓝给学生们组织了一场考试,卷面总分为 100 分,每个学生的得分都是一个 0 到 100 的整数. 如果得分至少是 60 分,则称为及格.如果得分至少为 85 分,则称为优秀. ...

  8. 【蓝桥杯官网试题 - 历届试题】小朋友排队(逆序数,树状数组)

    题干: 问题描述 n 个小朋友站成一排.现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友. 每个小朋友都有一个不高兴的程度.开始的时候,所有小朋友的不高兴程度都是0. 如果某 ...

  9. 【蓝桥杯官网试题 - 历届试题】格子刷油漆(dp)

    题干: 问题描述 X国的一段古城墙的顶端可以看成 2*N个格子组成的矩形(如下图所示),现需要把这些格子刷上保护漆. 你可以从任意一个格子刷起,刷完一格,可以移动到和它相邻的格子(对角相邻也算数),但 ...

最新文章

  1. 语音文件转成文字怎么转
  2. 比较MongoDB在公有云上的性能:AWS、Azure和Digital Ocean
  3. 教你如何rEFIt-让你开机免按option!
  4. Docker入门系列8
  5. matlab RBF 神经网络拟合
  6. 为什么国外程序员加班少?他们这样评价国内996和技术公众号
  7. 【Python】处理UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xa2 in position…
  8. 推荐!京东开源姿态跟踪新框架LightTrack!
  9. 【Flink】Generic types have been disabled in the ExecutionConfig and type KryoSerializer Row
  10. Sentinel流控规则_关联_分布式系统集群限流_线程数隔离_削峰填谷_流量控制_速率控制_服务熔断_服务降级---微服务升级_SpringCloud Alibaba工作笔记0035
  11. Linux 任务计划、周期性任务计划
  12. angular学习之路(一)
  13. emacs org-mode 常用命令
  14. 批处理实现软件静默批量安装
  15. vue 自定义marquee横向无缝滚动组件
  16. Android通过蓝牙获取设备的通讯录、通话记录等
  17. 这些中国顶级黑客带来的价值远比负面影响多!
  18. 如何实现上传多个图片并依次展示_在一张PowerPoint中插入多张图片如何让这些图片能依次播放...
  19. Android列表视图(ListView--SimpleAdapter)学习
  20. 学会区分 RNN 的 output 和 state

热门文章

  1. oracle 9i从入门到精通读书笔记2
  2. android 从assets和res中读取文件(转)
  3. [剑指offer]面试题第[50]题[JAVA][第一个只出现一次的字符][哈希表][HashMap]
  4. 计算机科学中的研究成果,田聪教授团队科研成果在计算机科学顶会LICS 2020发表...
  5. java垃圾回收机制_干货:Java 垃圾回收机制
  6. java se程序设计课后答案,JAVA SE程序设计及实践
  7. java.nio.file 找不到_java - 断言该错误:无法访问路径(找不到java.nio.file.Path) - 堆栈内存溢出...
  8. C#控件跨线程内容更新
  9. php 伪静态是什么意思,路由与伪静态
  10. 如何写一篇MBA论文-涉及matlab建模