傳送門
解題思路
直接用洛谷題解!
說的好!
怎麼求有向圖的歐拉路徑呢?
如果有起點,從起點出發,然後不斷dfs,對每個點記錄其出邊已經到了哪一條,然後當一個點的出邊都遍歷完的時候就把這條邊加入棧中。
這樣就找到了一條合法的歐拉路徑。
可以使用當前弧優化,時間優化到O(n+m)。
這個題因爲要求字典序最小,所以可以先對每個節點的出邊按照出點編號sort一遍。
所以用vector存圖便於sort。
AC代碼
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<bitset>
#include<stack>
using namespace std;
const int maxn=2e5+5;
vector<int> ve[maxn];
stack<int> s;
int now[maxn],n,m,in[maxn],out[maxn],vis1,vis2;
void dfs(int u){
for(int i=now[u];i<ve[u].size();i=now[u]){
now[u]++;
dfs(ve[u][i]);
}
s.push(u);
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=m;i++){
int u,v;
cin>>u>>v;
ve[u].push_back(v);
out[u]++;
in[v]++;
}
for(int i=1;i<=n;i++){
if(in[i]==out[i]) continue;
if(in[i]-out[i]==1){
if(!vis1) vis1=i;
else{
cout<<"No";
return 0;
}
continue;
}
if(out[i]-in[i]==1){
if(!vis2) vis2=i;
else{
cout<<"No";
return 0;
}
continue;
}
cout<<"No"<<endl;
return 0;
}
for(int i=1;i<=n;i++) sort(ve[i].begin(),ve[i].end());
if(vis2) dfs(vis2);
else dfs(1);
while(!s.empty()){
cout<<s.top()<<' ';
s.pop();
}
return 0;
}