一开始想用并查集后来参考了别人的代码,又发现了可以用拓扑排序做
emmmmm
1 并查集+dfs
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
vector<int> v[maxn];
int f[maxn],vis[maxn];
int n,x,y,e,s,flag;
void init(){
for(int i=0;i<=n;i++)
f[i]=i;
}
int find1(int a){
return f[a]==a?a:f[a]=find1(f[a]);
}
void dfs(int x){
if(flag) return ;
if(x==e){
int f=0,i;
for(i=1;i<=n;i++){
if(vis[i]==1)
{
if(f==0)
f=1;
else
cout<<" ";
cout<<i;
}
}
return ;
}
for(int i=0;i<v[x].size();i++){
int tmp=v[x][i];
if(!vis[tmp]){
vis[tmp]=1;
dfs(tmp);
vis[tmp]=0;
}
}
}
int main(){
int fx,fy,t;
scanf("%d",&n);
init();
for(int i=1;i<=n;i++){
scanf("%d %d",&x,&y);
fx=find1(x),fy=find1(y);
if(fx>fy) swap(fx,fy);
if(fx==fy) {
e=x;s=y;
}
else{
f[fy]=fx;
v[x].push_back(y);
v[y].push_back(x);
}
}
vis[s]=1;
dfs(s);
return 0;
}
2 拓扑排序 找度为一的点 最后没有被找到的点在环上,
环上每个点的度最少为2
#include<vector>
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
const int maxn=1e5+5;
int digit[maxn];
vector<int> v[maxn];
int vis[maxn];
void topsort(int n){
queue<int> q;
for(int i=1;i<=n;i++){
if(digit[i]==1)
{
q.push(i);
vis[i]=1;
}
}
while(!q.empty()){
int cur=q.front();
q.pop();
for(int i=0;i<v[cur].size();i++){
int tmp=v[cur][i];
digit[tmp]--;
if(digit[tmp]==1)
{
q.push(tmp);
vis[tmp]=1;
}
}
}
int f=0;
for(int i=1;i<=n;i++){
if(vis[i]==1) continue;
if(f) cout<<" ";
cout<<i;
f=1;
}
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d %d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
digit[x]++;digit[y]++;
}
topsort(n);
return 0;
}