有注释
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int M=2e6+110;
//全局量
//快读
int read(){
int sum=0,k=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')k=-1;c=getchar();}
while(c>='0'&&c<='9'){sum=sum*10+c-48;c=getchar();}
return sum*k;
}
//链式前向星
struct w{
int next,to;
//这一条边是否能走
bool cut;
}e[M];
int head[M],k=0;
void add(int u,int v){
e[++k].next=head[u];
e[k].to=v;
head[u]=k;
}
//---------------------------------------------------------------------------------------------------------------------
// 时间戳 tajan
int time_stamp=0,dfn[M];
// 环上的点集 环的大小
int ring[M],len=0;
//该点的爹
int fa[M];
// 该点是否在环上 是否有环
bool inring[M],ok=false;
void find_ring_dfs(int u,int ft){
dfn[u]=++time_stamp;
for(int i=head[u];i;i=e[i].next)
if(e[i].to!=ft){
if(dfn[e[i].to]==0){
fa[e[i].to]=u;
find_ring_dfs(e[i].to,u);
}
else if(dfn[e[i].to]>=dfn[u]){
ok=true;
ring[++len]=u;
inring[u]=1;
for(int v=e[i].to;v!=u;v=fa[v]){
ring[++len]=v;
inring[v]=1;
}
}
}
}
//---------------------------------------------------------------------------------------------------------------------
//dfs找最短路
//二维set某个点可以走到的下一个点的集合 自带排序
multiset<int>s[50005];
//ans是当前答案,res是最优答案
int ans[M],res[M],cnt=0;
void ans_dfs(int u,int fa){
s[u].clear();
ans[++cnt]=u;
//走到了u 将u加入当前答案
//u可以走到的下一个位置
for(int i=head[u];i;i=e[i].next){
if(e[i].to!=fa&&e[i].cut==0)//这条边不是断边
s[u].insert(e[i].to);
}
while(!s[u].empty()){
//去下个地方
ans_dfs(*s[u].begin(),u);
s[u].erase(*s[u].begin());
}
}
signed main(){
//读入
int n=read(),m=read();
while(m--){
//初始化
int u=read(),v=read();
add(u,v),add(v,u);
}
//判断有无环,有环就把环找出来
find_ring_dfs(1,0);
if(ok==0){
//没有环 从一开始走(字典序max)只有一条路
ans_dfs(1,0);
for(int i=1;i<=cnt;i++)
printf("%lld ",ans[i]);
}
else{
memset(res,0x3f3f3f3f,sizeof(res));
//初始设置极大值
for(int i=1;i<=len;i++){
//x是环上一点
int x=ring[i],y;
//y是x为k时的邻边
if(x%2==1) y=x+1;
else y=x-1;
//枚举该处边为断边
e[x].cut=e[y].cut=1;
//从1开始走
ans_dfs(1,0);
for(int j=1;j<=cnt;j++){
if(ans[j]<res[j])
for(int kk=j;kk<=cnt;kk++) res[kk]=ans[kk];
else if(ans[j]>res[j])break;
//比较,找字典序最大
}
e[x].cut=e[y].cut=0;
//回溯
memset(ans,0,sizeof(ans));
cnt=0;
}
for(int i=1;i<=n;i++) printf("%lld ",res[i]);
}
return 0;
}
/*
6 5
1 3
2 3
2 5
3 4
4 6
*/
无注释
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int M=4e5+110;
int read(){
int sum=0,k=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')k=-1;c=getchar();}
while(c>='0'&&c<='9'){sum=sum*10+c-48;c=getchar();}
return sum*k;
}struct w{int next,to;bool cut;}e[M];
int head[M],k=0;
void add(int u,int v){e[++k].next=head[u];e[k].to=v;head[u]=k;}
int time_stamp=0,dfn[M],ring[M],len=0,fa[M];
bool inring[M],ok=false;
void find_ring_dfs(int u,int ft){
dfn[u]=++time_stamp;
for(int i=head[u];i;i=e[i].next) if(e[i].to!=ft)
if(dfn[e[i].to]==0) fa[e[i].to]=u,find_ring_dfs(e[i].to,u);
else if(dfn[e[i].to]>=dfn[u]){
ok=true;
ring[++len]=u;
inring[u]=1;
for(int v=e[i].to;v!=u;v=fa[v]) ring[++len]=v,inring[v]=1;
}
}
multiset<int>s[50005];
int ans[M],res[M],cnt=0;
void ans_dfs(int u,int fa){
s[u].clear();
ans[++cnt]=u;
for(int i=head[u];i;i=e[i].next){
if(e[i].to!=fa&&e[i].cut==0) s[u].insert(e[i].to);
}
while(!s[u].empty()){
ans_dfs(*s[u].begin(),u);
s[u].erase(*s[u].begin());
}
}
signed main(){
int n=read(),m=read();
while(m--){
int u=read(),v=read();
add(u,v),add(v,u);
}
find_ring_dfs(1,0);
if(ok==0){
ans_dfs(1,0);
for(int i=1;i<=cnt;i++)printf("%lld ",ans[i]);
}
else{
memset(res,0x3f3f3f3f,sizeof(res));
for(int i=1;i<=len;i++){
int x=ring[i],y;
if(x%2==1) y=x+1;
else y=x-1;
e[x].cut=e[y].cut=1;
ans_dfs(1,0);
for(int j=1;j<=cnt;j++){
if(ans[j]<res[j])
for(int kk=j;kk<=cnt;kk++) res[kk]=ans[kk];
else if(ans[j]>res[j])break;
}
e[x].cut=e[y].cut=0;
memset(ans,0,sizeof(ans));
cnt=0;
}
for(int i=1;i<=n;i++) printf("%lld ",res[i]);
}
return 0;
}
/*
6 5
1 3
2 3
2 5
3 4
4 6
*/
感觉脑袋尖尖的,求调