80.欧拉回路

欧拉回路

定义

一个图,若能够找到一条路径,使得可以遍历完所有的边且不重复,则这样的图称为欧拉图,这条路径称为欧拉路径,若路径闭合也称为欧拉回路。

性质


Hierholzer 算法

Hierholzer算法是一种可以在时间复杂度 O(|E|) 内求出无向图或有向图的欧拉路径(如果有的话)的算法。

首先要判断这个图有没有欧拉路径,判断方法就是前面的定理

整个过程是递归实现的

无向图的欧拉路径

洛谷 P2731 [USACO3.3] 骑马修栅栏 Riding the Fences

#include <bits/stdc++.h>

int main() {
    freopen ("in.in", "r", stdin);
    int n, m; std::cin >> m; n = 1050;
    std::vector<std::vector<std::pair<int, int>>> g(n + 1);
    std::vector<int> du(n + 1, 0);
    int cnt = 0;
    for (int i = 1; i <= m; i++) {
        int x, y; std::cin >> x >> y;
        g[x].push_back({y, cnt++});
        g[y].push_back({x, cnt++});
        du[x]++; du[y]++;
    }

    for (int i = 1; i <= n; i++)
        std::sort(g[i].begin(), g[i].end());

    int st = -1; // 起点
    for (int i = 1; i <= n; i++) {
        if (du[i] > 0 && st == -1) st = i;
        if (du[i] & 1) {
            st = i;
            break;
        }
    }

    std::vector<int> vis(cnt, 0);
    std::stack<int> stk;
    std::function<void(int)> dfs = [&](int u) {
        for (auto &[v, id] : g[u]) {
            if (vis[id]) continue;
            vis[id] = 1; vis[id ^ 1] = 1;
            dfs(v);
        }
        stk.push(u);
    };

    dfs(st);

    while (!stk.empty()) {
        std::cout << stk.top() << "\n";
        stk.pop();
    }

    return 0;
}