[模板] 欧拉回路

欧拉路

给定一个无向图, 求一条恰好经过每条边恰好一次的路径.

如果所有点度数均为偶数, 存在欧拉回路; 如果有且仅有两个点度数为奇数, 存在以这两个点为起点, 终点的欧拉路.

欧拉路是一个连通图, 可以分解为一条点不相交的路径 + 若干个环.

求欧拉路

直接搜索, 那么出栈序列的逆序即为欧拉路.

代码

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
using namespace std;
#define rep(i,l,r) for(register int i=(l);i<=(r);++i)
#define repdo(i,l,r) for(register int i=(l);i>=(r);--i)
#define il inline
typedef double db;
typedef long long ll;

//---------------------------------------
const int nsz=550,msz=1050;
int n,m;
int deg[nsz];
multiset<int> edge[nsz];
void adde(int f,int t){edge[f].insert(t);edge[t].insert(f);}
void erase(int f,int t){edge[f].erase(edge[f].find(t));}

int ans[nsz],pa=0;
void dfs(int p){
	for(multiset<int>::iterator i=edge[p].begin();i!=edge[p].end();i=edge[p].begin()){
		int v=*i;
		edge[p].erase(i);
		edge[v].erase(edge[v].find(p));
		dfs(v);
	}
	ans[++pa]=p;
}

int main(){
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>m;
	int a,b;
	rep(i,1,m)cin>>a>>b,++deg[a],++deg[b],adde(a,b),n=max(n,max(a,b));
	int fr=-1;
	rep(i,1,n){
		if(deg[i]&&fr==-1)fr=i;
		if(deg[i]&1){fr=i;break;}
	}
	dfs(fr);
	repdo(i,pa,1)cout<<ans[i]<<'\n';
	return 0;
}
posted @ 2019-07-10 14:00  Ubospica  阅读(193)  评论(0编辑  收藏  举报