图论:欧拉(回)路模板

点击查看代码块
/*
找字典序最小的欧拉路,也可以做欧拉回路
*/
#include <bits/stdc++.h>

#define ed end()
#define bg begin()
#define mp make_pair
#define pb push_back
#define v(T) vector<T>
#define all(x) x.bg,x.ed
#define newline puts("")
#define si(x) ((int)x.size())
#define rep(i,n) for(int i=1;i<=n;++i)
#define rrep(i,n) for(int i=0;i<n;++i)
#define srep(i,s,t) for(int i=s;i<=t;++i)

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn = 2e4+10;
const int inf = 0x7f7f7f7f;
const ll inf_ll = 1ll*inf*inf;
const int Mod = 1e9+7;
const double eps = 1e-7;

int n;
int path[maxn];
int g[510][510];
int deg[maxn],cnt=0;

int Max = 0,Min = inf;

void dfs(int u){//欧拉路板子
    for (int i=Min;i<=Max;i++){
        if(g[u][i]){
            g[u][i]--;g[i][u]--;//可能两点之间有多条边
            dfs(i);    
        }
    }
    path[++cnt] = u;//记录路径信息
}

int main(){
    scanf("%d",&n);
    rep(i,n){
        int u,v;
        scanf("%d %d",&u,&v);
        Max=max(Max,u);Max=max(Max,v);
        Min=min(Min,u);Min=min(Min,v);
        g[u][v]++;g[v][u]++;
        deg[u]++;deg[v]++;
    }
    int k = Min;
    for (int i=Min;i<=Max;i++){
        if(deg[i] & 1){//从第一个奇数度数的点开始找欧拉路
            k=i; break;
        }
    }
    dfs(k);
    for (int i=cnt;i>=1;i--){//记录的时候是反向记录的,所以输出的时候也需要反向输出
        printf("%d
",path[i]);
    }
    return 0;
}
你将不再是道具,而是成为人如其名的人
原文地址:https://www.cnblogs.com/wsl-lld/p/13451523.html