欧拉回路

分为有向与无向。

欧拉图为有欧拉回路的图。

判定

无向图

判定为所有有边的点连通且每个点的度数为偶数。

我们可以给出一种构造使得上述条件充要。

对于起点 \(x\),每次取出一个从 \(x\) 到 \(x\) 的简单环,把这个环走一遍。这样做之后每个点度数显然还是偶数,之后可能将图分为若干连通块,这些联通块与这个简单环一定有交,那我们在走这个简单环的时候顺路把这些连通块也走了即可,由于其他连通块是子问题,到最深处就是一个点一定有解,那么可以归纳证明。

有向图

所有有边的点弱连通且每个点入度等于出度。

证明与上面类似。

构造

给出最经典的 \(Hierholzer\) 算法。

下面还是考虑无向图,有向图类似。

首先我们其实已经有了一种判定一样的做法,但是有些麻烦,我们存在一些方法简化。

我们还是考虑从一个点开始走,之后递归到子问题再归纳。

我们考虑对于一个点 \(u\) 任选一个出边 \(u \to v\),然后直接递归下去做。

假设我们现在处理的是剩下的边从 \(u\) 开始,到 \(T\) 结束的路径。

若删去 \(u\to v\) 这条边后图联通,我们可以直接递归到从 \(v\) 开始到 \(T\) 结束的子问题,因为你删去这个点后由于你当前处理的问题是从 \(u\) 到 \(T\) 的欧拉路径或回路。

若此时 \(deg_u \bmod 2 =0\),那么说明 \(T = u\),删去这条边后 \(deg_v \bmod 2 =1\)且 \(u \bmod 2 =1\),其他点度数也还是偶数,这就递归到一个欧拉路径的子问题。

否则 \(deg_u \bmod 2 =1\) 且 \(deg_T \bmod 2 =1\),那么 \(deg_v \bmod 2 =0\),那么你删掉这条边后, \(deg_v \bmod 2 =1\) 且 \(deg_T \bmod 2 =1\),这显然是子问题。

否则如果不联通的话,那么显然对于一个中心点 \(u\) 对应的边 \(u \to v\),只有一个这样的边,不然一定无解,且这条边一定最后走。

那么我们有一个 \(O((n+m)^2)\) 的做法,即你每次先判定删一条边后是否联通再走。

考虑优化上述过程,我们直接设函数 \(ouler(i)\) 表示走完 \(i\) 这个连通块所有边的方案,对于中心点 \(u\),遍历所有 \(u \to v\),若这条边没有被经过,依次做 \(ouler(v)\),由于是递归构造每做完一个就把这个点插入队头。

考虑这样做的正确性,就论前面的平方做法的情况,这个做法优化掉了判断连通的过程,但是把每次进入一个点就把这个点加入路径队列,换成了递归往下,直到做完这个点,在把其倒序放入序列。

后面这种做法的高妙之处在于,若你走到了不联通的块时,\(ouler(v)\) 一定会直接处理完那个块,并且把其放在当前递归处理的位置的最后面,就像我们前面判定联通设想的那样。

因为这个做法它定义的 \(ouler(x)\) 是构造完当前连通块的答案。所以有断边的话,如果没有走到这个断边对应的连通块,它是不会停下插入点的,因为它没有处理完这个大的连通块。

只有走到断边连通块时它才会插入点,于是这样做可以默认让断边连通块被放在最后加入的位置,就省去的判断联通的时间从而优化到了 \(O(n+m)\)。

给出核心代码

void ouler(int now){
    for(int &i=cur[now];i<vec[now].size();){
        auto [v,id]=vec[now][i++];
        if(vis[id]) continue;
        vis[id]=vis[id^1]=1;
        ouler(v);
    }stk[++tp]=now;
}

对于欧拉回路还有一些精妙的有关图论建模的例题。
例如 CF1361C,CF1458D,P16832。

其中还存在一个结论:将一张有向图划分成若干不交的路径,覆盖整张图,最小路径数。有结论 \(ans =\max(1, \frac{\sum|in_i - out_i |}{2})\)。

证明:

显然为下界,下面给出一组构造。

首先 $\sum in_i = out_i $,对于 \(in_x - out_x \gt 0\) 的点,考虑连出 \(in_x - out_x\) 条虚边,否则连入 \(-(in_x - out_x)\) 条虚边。

由于度数和为偶数,所有总有这样的方案满足要求。这样干之后原图显然已经存在欧拉回路,在跑欧拉路径时每经过一条虚边 \(u \to v\),设上一条虚边 \(x \to y\),则将中间 \(y \to u\) 的路径记做一条划分路径,显然最后会将原图覆盖且总数为虚边个数,于是得证。

其中与 \(1\) 取 \(\max\) 是对于欧拉回路的一种特殊处理。

posted @ 2026-09-27 21:42  lmy333  阅读(9)  评论(0)    收藏  举报