问题描述
小明的实验室有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
拓扑排序
无向图拓扑排序一遍然后输出度为4的所有结点
#include<iostream>
#include<cstring>
using namespace std;
const int N = 100010, M = 200010;
int h[N], e[M], ne[M], idx;
int n;
int w[N];
int q[M], hh, tt = -1;
void topsort(){
for(int i = 1; i <= n; i ++)
if(w[i] == 2) q[++ tt] = i;
while(hh <= tt){
int t = q[hh ++];
for(int i = h[t]; ~i; i = ne[i]){
int j = e[i];
w[j] -= 2;
if(w[j] == 2) q[++ tt] = j;
}
}
}
void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
w[a] ++;
w[b] ++;
}
int main(){
memset(h, -1, sizeof h);
cin >> n;
for(int i = 0; i < n; i ++){
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
topsort();
for(int i = 1; i <= n; i ++)
if(w[i] == 4) cout << i << ' ';
return 0;
}
并查集判断环,dfs得结果
在输入边的时候往并查集里面加边ab,如果两个结点ab已经在一个集合里面,那么说明加了这条边以后出现了环,所以可以设置a为起点,b为终点然后dfs一遍即可,注意要走a到b的较长的一条路,否则就只有ab了
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 100010, M = 200010;
int h[N], e[M], ne[M], idx;
int n;
int start, aim;
int p[N];
vector<int> res;
int st[N];
struct{
int a, b;
}edges[N];
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
void add(int a, int b){
e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
}
int dfs(int u){
res.push_back(u);
st[u] = 1;
if(u == aim) return 1;
for(int i = h[u]; i != -1; i = ne[i]){
int j = e[i];
if(st[j] == 0){
if(u == start && j == aim) continue;
if(dfs(j)) return 1;
res.pop_back();
st[j] = 0;
}
}
return 0;
}
int main(){
memset(h, -1, sizeof h);
cin >> n;
for(int i = 1; i <= n; i ++) p[i] = i;
for(int i = 0; i < n; i ++){
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
int x = find(a), y = find(b);
if(x == y)
start = a, aim = b;
else p[x] = y;
}
dfs(start);
sort(res.begin(), res.end());
for(int i = 0; i < res.size(); i ++) cout << res[i] << ' ';
return 0;
}