传送门
解题思路
直接用洛谷题解!
说的好!
怎么求有向图的欧拉路径呢?
如果有起点,从起点出发,然后不断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;
}