给定一棵n个点的基环树。
找出它的环并按顺序依次输出环上的节点编号。
由于环可能有多种输出方法(将环旋转或翻转),请你输出字典序最小的一种。
37分,求助
#include<bits/stdc++.h>
using namespace std;
#define N 1000010
typedef long long ll;
ll n;
ll x,y;
ll to[N],hd[N],nxt[N],tot=1;
ll fa[N],vst[N];
ll loop[N],top=0;
ll times=0;
void add(ll x,ll y){
to[++tot]=y; nxt[tot]=hd[x]; hd[x]=tot;
}
void findloop(ll x){
// cout<<x<<endl;
vst[x]=++times;
for(ll i=hd[x];i;i=nxt[i]){
ll y=to[i];
if(y==fa[x]) continue;
if(vst[y]){
if(vst[y]<vst[x]) continue;
loop[++top]=y;
for(;y^x;y=fa[y]) loop[++top]=fa[y];
//,cout<<loop[top]<<endl;
return ;
}
else fa[y]=x,findloop(y);
}
return ;
}
ll smaller(ll x,ll y){
stringstream ss,ss2;
string r1;
string r2;
ss<<x;
ss>>r1;
// cout<<r1<<endl;
ss2<<y;
ss2>>r2;
// cout<<"*"<<r2<<endl;
// cout<<r1<<' '<<r2<<endl;
if(r1>r2) return y;
return x;
}
int main(){
// cout<<smaller(3,5)<<endl;
memset(vst,0,sizeof(vst));
cin>>n;
for(ll i=1;i<=n;i++) cin>>x>>y,add(x,y),add(y,x);
fa[1]=0;
findloop(1);
// for(int i=1;i<=top;i++) cout<<loop[i]<<' ';
// cout<<endl;
for(ll i=top+1;i<=2*top;i++) loop[i]=loop[i-top];
for(ll i=top*2+1;i<=top*3;i++) loop[i]=loop[i-top*2];
ll max_=top+1;
// for(ll i=1;i<=3*top;i++) cout<<loop[i]<<' ';
for(ll i=top+2;i<=2*top;i++)
if(smaller(loop[max_],loop[i])==loop[i]) max_=i;
// cout<<max_-n<<endl;
//cout<<max_<<endl;
if(smaller(loop[max_-1],loop[max_+1])==loop[max_-1]){
// cout<<max_<<' '<<max_-1<<endl;
for(ll i=max_;i>=max_-top+1;i--) cout<<loop[i]<<' ';
cout<<endl;
}
else{
for(ll i=max_;i<=max_+top-1;i++) cout<<loop[i]<<' ';
cout<<endl;
}
return 0;
}