分析
首先可以贪心选择字典序小的点先跑,所以可以把边按照小到大排序,但是由于邻接表是反过来的,所以说要反过来排序,好的
,那么
m
=
n
−
1
m=n-1
m=n−1的子任务就可以做完了,但是基环树这个子任务是不可以的,因为一条边最多跑两次,既然存在环,所以要把环断掉,首先先跑一遍拓扑排序,判断环上的点,并对于环断边,用树的方式记录字典序最小排列
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <queue>
#include <cstring>
#define rr register
using namespace std;
struct node{int x,y,next;}e[10011]; bool v[5011];
int n,m,ttt[5011],p[10011],dfn[5011],k,tot,ls[5011],deg[5011],ddfn[5011];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
bool cmp(node x,node y){return x.y>y.y;}
inline void dfs(int x,int t){
dfn[++tot]=x,v[x]=1;
for (rr int i=ls[x];i;i=e[i].next){
if (v[e[i].y]||t==i||t==p[i]) continue;
dfs(e[i].y,t);
}
}
inline void pd(){
for (rr int i=1;i<=n;++i)
if (dfn[i]<ddfn[i]) break;
else if (dfn[i]>ddfn[i]) return;
for (rr int i=1;i<=n;++i) ddfn[i]=dfn[i];
}
inline void answ(int now){
rr queue<int>q,q1;
q.push(now);
while (q.size()){
rr int x=q.front(); q.pop(); deg[x]=1;
for (rr int i=ls[x];i;i=e[i].next)
if (deg[e[i].y]>1){q1.push(i); q.push(e[i].y); break;}
}
for (rr int i=ls[e[q1.back()].y];i;i=e[i].next)
if (e[i].y==now) {q1.push(i); break;}
while (q1.size()){
memset(v,0,sizeof(v)); tot=0;
dfs(1,q1.front()); q1.pop(); pd();
}
}
signed main(){
n=iut(); m=iut(); k=1;
for (rr int i=1;i<=m;++i){
rr int x=iut(),y=iut();
e[++k]=(node){x,y,i+1},
e[++k]=(node){y,x,i+1};
++deg[x],++deg[y];
}
sort(e+2,e+1+k,cmp);
for (rr int i=2;i<=k;++i){
if (ttt[e[i].next])
p[i]=ttt[e[i].next],
p[ttt[e[i].next]]=i;
ttt[e[i].next]=i,e[i].next=0;
}
for (rr int i=2;i<=k;++i)
e[i].next=ls[e[i].x],ls[e[i].x]=i;
if (m==n-1){
dfs(1,0);
for (rr int i=1;i<=n;++i) printf("%d%c",dfn[i],i==n?10:32);
return 0;
}
rr queue<int>q;
for (rr int i=1;i<=n;++i) ddfn[i]=n-i+1;
for (rr int i=1;i<=n;++i) if (deg[i]==1) q.push(i);
while (q.size()){
rr int x=q.front(); q.pop();
for (rr int i=ls[x];i;i=e[i].next)
if (deg[e[i].y]>1){
if ((--deg[e[i].y])==1)
q.push(e[i].y);
}
}
for (rr int i=1;i<=n;++i)
if (deg[i]>1){
answ(i);
for (rr int j=1;j<=n;++j) printf("%d%c",ddfn[j],j==n?10:32);
return 0;
}
}