原題連結
題解
鏈式前向星版本的尤拉回路dfs
void dfs(int u){ for (int i=head[u];i>0;i=head[u]){ head[u]=Next[i]; //走過的路直接跳過 dfs(to[i]); } que[l++]=u; }
接下來的難點是如何字典序搜尋。我們在dfs的時候直接讓走字典序最小的邊即可;而由於鏈式前向星是從後往前列舉的,我們需要對所有的邊進行排序。
bool cmp(Node a,Node b){ if (a.u!=b.u) return a.u<b.u; return a.v>b.v; //保證每次列舉都是字典序最小的邊 }
code
#include<bits/stdc++.h> using namespace std; const int N=1e5+5; const int M=2e5+5; int head[N],Next[M],to[M],in[N],out[N]; struct Node{ int u,v; }; Node a[M]; bool cmp(Node a,Node b){ if (a.u!=b.u) return a.u<b.u; return a.v>b.v; } int cnt=1,l=0; int que[M]; void build(int i){ Next[cnt]=head[a[i].u]; to[cnt]=a[i].v; head[a[i].u]=cnt++; } void dfs(int u){ for (int i=head[u];i>0;i=head[u]){ head[u]=Next[i]; // cout<<u<<" "<<to[i]<<endl; dfs(to[i]); } que[l++]=u; } int main(){ int n,m; cin>>n>>m; for (int i=1;i<=m;i++){ cin>>a[i].u>>a[i].v; in[a[i].v]++; out[a[i].u]++; } int n1=0,n2=0,start=1,end=n; for (int i=1;i<=n;i++){ if (in[i]-out[i]==1){ n1++; end=i; continue; } if (out[i]-in[i]==1){ n2++; start=i; continue; } if (in[i]!=out[i]){ cout<<"No\n"; return 0; } } if ((n1==0 && n2==0) || (n1==1 && n2==1)){ sort(a+1,a+m+1,cmp); // for (int i=1;i<=m;i++) cout<<a[i].u<<" "<<a[i].v<<endl; for (int i=1;i<=m;i++) build(i); dfs(start); while (l){ if (l) cout<<que[--l]<<" "; else cout<<que[--l]; } } else cout<<"No\n"; return 0; }