求助站外题
  • 板块题目总版
  • 楼主VickeyTugan
  • 当前回复1
  • 已保存回复1
  • 发布时间2021/6/25 20:03
  • 上次更新2023/11/4 21:30:37
查看原帖
求助站外题
343733
VickeyTugan楼主2021/6/25 20:03

给定一棵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;
}
2021/6/25 20:03
加载中...