欧拉路径

参考资料: OI-wiki

0. 一些概念#

首先让我们明确几个概念.

我们定义, 通过图中所有边恰好一次的通路称为欧拉通路, 若该路为回路则称为欧拉回路.
若一个图存在欧拉回路, 则称该图为欧拉图. 若不存在欧拉回路但存在欧拉通路, 该图成为半欧拉图.

无向图 (半) 欧拉图判定:

  • 一个连通图是无向欧拉图等价于该图中点的度数均为偶数.
  • 一个连通图是无向半欧拉图等价于该图中只有两个点的度数为奇数 (起点和终点).

上面两个判定是众所周知的.

对于有向图, 我们也可以进行判定:

  • 一个图是有向欧拉图等价于该图为一个 SCC 且每个点的入度和出度相同.
  • 一个图是有向半欧拉图等价于:
    • 若将边都视为无向边则该图连通;
    • 只存在一个点, 它的出度等于入度加一, 该点为起点;
    • 只存在一个点, 它的入度等于出度加一, 该点为终点;
    • 除起点和终点外的所有点入度和出度相同.

也很容易理解.

1. 求欧拉路径#

luoguP7771 【模板】欧拉路径

题意: 给定一个有向图, 输出其字典序最小的欧拉路径 (不存在输出 No).

首先根据上面的判定定理我们容易判定该图是否为(半)欧拉图并找出欧拉路径的起点和终点.
然后直接 dfs 就完事了. 每次我们选择第一条还没有走过的路径, 返回的时候把点压入栈即可.
需要注意的是我们需要注意一点细节, 需要记录现在已经选到第几条边了, 不要重复遍历已经走过的边.
要保证字典序最小只需要对邻接表排一下序就行了.

code:

const int maxn=100010;
int n,m,s=1,t,scnt,tcnt,indeg[maxn],outdeg[maxn],cur[maxn];
vector<int> G[maxn];
stack<int> path;
void dfs(int u)
{
    for(int i=cur[u];i<G[u].size();i=cur[u])
    {
        cur[u]=i+1;
        dfs(G[u][i]);
    }
    path.push(u);
}
bool check()
{
    for(int i=1;i<=n;i++)
    {
        if(indeg[i]==outdeg[i])continue;
        if(indeg[i]==outdeg[i]+1)
        {
            tcnt++;
            t=i;
            if(tcnt>1)return 0;
            continue;
        }
        if(indeg[i]+1==outdeg[i])
        {
            scnt++;
            s=i;
            if(scnt>1)return 0;
            continue;
        }
        return 0;
    }
    return 1;
}
int main()
{
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        int u=read(),v=read();
        indeg[v]++;outdeg[u]++;
        G[u].push_back(v);
    }
    if(!check())
    {
        printf("No");
        return 0;
    }
    for(int i=1;i<=n;i++)sort(G[i].begin(),G[i].end());
    dfs(s);
    while(!path.empty())
    {
        printf("%d ",path.top());
        path.pop();
    }
    return 0;
}

2. 一些例题#

CF508D Tanya and Password

luoguP3520 [POI2011] SMI-Garbage

luoguP3443 [POI2006]LIS-The Postman

CF527E Data Center Drama

作者:pjykk

出处:https://www.cnblogs.com/pjykk/p/16555636.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   pjykk  阅读(64)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示