欧拉路径 & P7771 【模板】欧拉路径

传送门


解题思路

直接用洛谷题解!
image
说的好!

怎么求有向图的欧拉路径呢?

如果有起点,从起点出发,然后不断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;
}
posted @ 2021-11-19 11:35  尹昱钦  阅读(121)  评论(0编辑  收藏  举报