【算法模板】图论:欧拉路

欧拉路径(欧拉通路):通过图中所有边的简单路。

欧拉回路:闭合的欧拉路径。(即一个环,保证每条边都通过且仅通过一次)

欧拉图:包含欧拉回路的图。

半欧拉图:具有欧拉路径但不具有欧拉回路的图

欧拉路存在性

首先,图应该是连通图。 在编程时用DFS或者并查集来判断连通性。

其次,判断图是否存在欧拉路或欧拉回路:

  1. 无向连通图的判断条件。 如果图中的点全都是偶点,则存在欧拉回路;任意一点都可以作为起点和终点。 如果只有两个奇点,则存在欧拉路,其中一个奇点是起点,另一个 是终点。 不可能出现有奇数个奇点的无向图。
  2. 有向连通图的判断条件。 把一个点上的出度记为1、入度记为-1,这个点上所有的 出度和入度相加就是它的度数。 一个有向图存在欧拉回路,当且仅当该图所有点的度数为0。 如果只有一个度数为1的点 、一个度数为-1的点,其他所有点的度数为0,那么存在欧拉路径,其中度数为1的是起点、度数为-1的是终点。

DFS算法

  1. 选择一个起始顶点作为当前顶点,初始化一个空的路径。
  2. 从当前顶点出发,逐步遍历其相邻的边和顶点。
  3. 对于每条遍历过的边,标记为已访问,并将其从图中删除。
  4. 递归地从相邻顶点进行DFS搜索,直至无法再往下进行为止。
  5. 如果所有的边都被访问过且当前顶点的出度为0,则把当前顶点添加到路径上,并返回上一级顶点。
  6. 继续回溯,寻找其他可能的路径,直到遍历完所有的顶点和边。

例题

P2731 USACO3.3 骑马修栅栏 Riding the Fences - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;
const int N=500;
int main(){
    int m;cin>>m;
    vector<vector<int>> G(N+1,vector<int>(N+1));
    vector<int> degree(N+1);
    for(int i=1;i<=m;++i){
        int u,v;cin>>u>>v;
        G[u][v]++,G[v][u]++;
        degree[u]++,degree[v]++;
    }
    int start=1;
    for(int i=1;i<=N;i++)if(degree[i]&1){
        start=i;
        break;
    }
    vector<int> ans;
    function<void(int)> dfs=[&](int x){
        for(int i=1;i<=N;i++)
            if(G[x][i]){
                G[x][i]--,G[i][x]--;
                dfs(i);
            }
        ans.push_back(x);
    };
    dfs(start);
    reverse(ans.begin(),ans.end());
    for(int i:ans)cout<<i<<endl;
    return 0;
}

Fluery算法*

  1. 选择起点

    • 如果存在欧拉回路,则可以从任意顶点开始。
    • 如果存在欧拉路径,则从度数为奇数的一个顶点开始。
  2. 路径构建

    • 选择一条边,但要避免选择桥(bridge),除非没有其他选择。桥是一条如果移除会导致图变得不连通的边。
    • 删除选择的边,并移动到下一个顶点。
    • 重复上述步骤,直到所有边都被遍历。
  3. 输出路径

    • 最后得到的路径即为欧拉路径或欧拉回路。

Hierholzer算法*

  1. 选择起点

    选择任意一个顶点作为起点。

  2. 构建子回路

    从起点出发,沿着未被访问过的边行走,直到回到起点,形成一个子回路。每次选择下一条边时,都确保该边未被访问过。

  3. 合并回路

    如果存在未被访问的边,则从该回路中的某个包含未被访问边的顶点出发,重复步骤2,形成一个新的子回路。将新子回路插入到原回路中。

  4. 重复

    重复步骤3,直到所有的边都被访问过。

  5. 输出欧拉回路

    最终得到的路径即为欧拉回路。

相关推荐
王老师青少年编程1 分钟前
csp信奥赛C++高频考点专项训练之贪心算法 --【部分背包问题】:部分背包问题
c++·算法·贪心·csp·信奥赛·部分背包问题
九思十安4 分钟前
HNU2026-算法设计与分析-笔记 3 摊还分析
笔记·算法
嘻嘻哈哈樱桃8 分钟前
牛客经典101题题解集--哈希
java·数据结构·python·算法·leetcode·职场和发展·哈希算法
自我意识的多元宇宙13 分钟前
【数据结构】 红黑树
数据结构·算法
wayz1115 分钟前
Day 15 编程实战:KMeans聚类与股票风格分类
算法·机器学习·分类·kmeans·聚类
不知名的老吴16 分钟前
数据结构与算法之排序算法
算法·排序算法
Brilliantwxx17 分钟前
【算法题】日期类算法题
开发语言·c++·笔记·程序人生·算法
穿条秋裤到处跑21 分钟前
每日一道leetcode(2026.04.27):检查网格中是否存在有效路径
算法·leetcode·职场和发展
我不是懒洋洋28 分钟前
【数据结构】二叉树链式结构的实现(二叉树的遍历、使用二叉树的基本方法、二叉树的创建和销毁)
c语言·数据结构·c++·经验分享·算法·链表·visual studio
水木流年追梦31 分钟前
CodeTop Top 300 热门题目8-字符串解码
linux·运维·服务器·前端·算法·leetcode