当前位置: 首页 > news >正文

欧拉回路

定义

欧拉路径是经过图中每条边恰好一次的路径,欧拉回路是经过图中每条边恰好一次的回路。

结论:(半)欧拉图判定:

  • (弱)连通;
  • 度数奇偶性。

欧拉回路要求所有点的度数是偶数,路径则允许两个节点有奇度数。

适用性 / 套路

就是一些常见套路和模型:

  • ... 和 ... 相差 1。(超级常见)

然后转换成:

  • 给边定向。

求解:Hierholzer 算法

在判定一个图具有欧拉回路后,进行该算法。

算法基于 dfs,每次搜索到一条边就标记,同时标记反向边(如有),并在该节点的邻接表中删除该边,保证复杂度是 \(O(|E|+|V|)\)

vector 存图实现:

此时 vector 里需要保存当前边的编号。每次取出从 vector::back() 取出,然后 vector::pop_back()

vector<pair<int, int>> e[E];
int stk[E], siz;
bool vis[E];
int tot, cur = 0;
void dfs(int u){while(!e[u].empty()){pair<int, int> edge = e[u].back();e[u].pop_back();int v = edge.first;if(vis[edge.second]) continue;vis[edge.second] = 1;dfs(v);stk[++siz] = edge.second;}
}

链式前向星实现

相较之下,链式前向星需要的修改极少。

只需要在遍历边时,int &i = head[u],即引用 head[u],自动修改,实现删边。

记得 tot 初始为 1,实现 e ^ 1e 的反边。

int head[N];
int to[E], nxt[E];
int tot = 1;
bool vis_e[M];
void add(int u, int v, int id){to[++tot] = v;nxt[tot] = head[u];eid[tot] = id;head[u] = tot;deg[v]++;
}
void dfs2(int u){for(int &i = head[u]; i; i = nxt[i]){if(vis_e[i]) continue;int v = to[i];vis_e[i] = vis_e[i ^ 1] = 1;int tmp = eid[i];dfs2(v);ans[++ans_cnt] = tmp;}
}

例题

Luogu P11762 走亲访友

屏幕截图 2025-08-11 193758

因为最后要求删边成一颗树,我们正难则反,考虑先找到这个树。

随便 dfs 出一颗生成树。

路径是陌生的,但回路是熟悉的。——MagicDark(赵海鲲)

可以考虑将限制变紧:要求起点和终点相同。

因为不在生成树上的边只能走一次,联想到欧拉回路(另一种解释)。

那么需要构造使得回路方案对应路径方案,即让每个点的度数为偶数。

  • 当前点已经偶度数,不管。

  • 当前点奇度数,复制它和父亲的连边,相当于要求走两遍。可以证明一定可以成功构造。

这样生成树的边只会至多经过两次,非生成树的变只会至多经过一次,路径长度至多为 \(n + m - 1 \leq k\)。(数据范围)

CodeForces 547D

屏幕截图 2025-08-11 194822

网格图的套路,建模可以连接一个点的横纵坐标。

于是转换为给每条边定向,事实上很多欧拉回路题都是转换成定向。两种方向对应颜色。

那么发现相差 1,这又是一个欧拉回路题的常见点——相差 1,因为不差就太简单了。

相差 1,出现奇度点,还是考虑怎么搞成偶数。新建超级源点 \(0\),连向所有奇度点即可。

\(O(n)\) 欧拉回路。

Luogu P9731 Balance

屏幕截图 2025-08-11 195609

这种 2 的幂不好搞怎么办,一般先去看 2 的情况怎么做。然后可以分治思想。

\(S = 2\)

此时,就是给两个数定顺序,就是给边定向了。

又是差 1,又是一个源点连向奇度点。

感觉这种题挺套路的。

\(S = 2 ^ k, k \gt 1\)

屏幕截图 2025-08-11 200437

http://www.aitangshan.cn/news/197.html

相关文章:

  • 8月11号
  • Orleans框架
  • ABC418——XNOR - love
  • 代码随想录算法训练营第五天(哈希表篇)|Leetcode242有效的字母异位词,Leetcode349两个数组的交集,Leetcode202快乐数,Leetcode1两数之和
  • 7种形态图
  • 百度智能云给“数字人”发工牌 - 详解
  • 1
  • 2025.8.11.模拟赛题目记录
  • Mysql 授予root在任意主机访问数据库的权限
  • Awesome Claude Code 资源大全
  • JAVA方法
  • echarts初始化占不满div, F12后又占满了
  • docker Ubuntu Docker 安装
  • arm LDR指令
  • QNAP QTS SSL Certificate 证书更新修复
  • Python入门学习(九)Python的高级语法与用法(二)闭包
  • 工程师团队如何打造4K流媒体设备的创新技术
  • 【题解】P4063 [JXOI2017] 数列
  • mount: /mnt/hgfs/vm_share: unknown filesystem type vmhgfs - hbg
  • 8月11日总结
  • OpenCV-鱼眼相机图像处理
  • 新高一暑假二期集训 Week 1
  • ZR 25 summer D6T1 题解 | 思维、数学(计算几何)
  • 线程安全的集合类 ConcurrentQueue、ConcurrentStack、BlockingCollection、ConcurrentBag、ConcurrentDictionary
  • 【自学嵌入式:stm32单片机】对射式红外传感器记次
  • Rime-weasel 中州韻輸入法-小狼毫 输入法候选框不显示拼音的解决办法
  • 从美世《中国员工敬业度员工体验白皮书》看AI如何改善员工体验
  • 线程安全的集合类 ConcurrentQueue、BlockingCollection、ConcurrentBag
  • 通达信指标泰乐1号战法指标分享(无偿分享全套指标)
  • 差分约束