[模板] 欧拉回路

欧拉路

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

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

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

求欧拉路

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

代码

#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;
}
上一篇:这是我见过最牛的报表制作神器!比Excel强大20倍!


下一篇:oracle主键自增