无向图找环。
用dfs来搜索环,两个参数,dfs(x,y),x表示当前点的位置,y表示前驱位置
然后搜除了前驱位置的点(也就是不回走,将有向图转为无向图),每走一个点给布尔数组赋1,直到搜到重复的点,说明发现了环。值得注意的时, 搜完有两种情况,起点在环上,起点不在环上。
当起点不在环上,再用一个dfs将起点与环节点(除了record)中间的所有布尔数组赋0。
最后输出布尔数组就好了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int MAX = 100010;
vector<int> arr[MAX];
int ok[MAX]={0};//记录在环上的点
int n;
int tag=0;//发现环时 变为1
int record;//记录形成环的那个节点,用来消除起点与该点之间的0
void dfs(int x,int y)//dfs搜环
{
ok[x]=1;
for(int i=0;i<arr[x].size();i++){
if(arr[x][i]==y)continue;
if(ok[arr[x][i]]){
tag=1;
record=arr[x][i];
return;
}
else{
dfs(arr[x][i],x);
}
if(tag==1)return;
}
ok[x]=0;
}
void re(int x)//将不再环上的点清0
{
ok[x]=0;
for(int i=0;i<arr[x].size();i++){
if(arr[x][i]==record){
return;
}
if(ok[arr[x][i]]){
re(arr[x][i]);
}
}
}
int main()
{
int a,b;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&a,&b);
arr[a].push_back(b);
arr[b].push_back(a);
}
dfs(1,0);
if(record!=1){
re(1);
}
for(int i=1;i<=n;i++)
if(ok[i])
printf("%d ",i);
return 0;
}
/*
8
7 3
7 2
2 4
2 8
3 4
3 5
4 1
5 6
*/