1. 程式人生 > 其它 >尤拉路徑 & P7771 【模板】尤拉路徑

尤拉路徑 & P7771 【模板】尤拉路徑

傳送門


解題思路

直接用洛谷題解!

說的好!

怎麼求有向圖的尤拉路徑呢?

如果有起點,從起點出發,然後不斷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;
}