Day44【欧拉回路】
反色刷
欧拉回路典中典 t r i c k trick trick。
不难想到把白边拆成 2 2 2 条,那么对于某个连通块,其最多会走一次回路,那就是欧拉回路(如果有两个回路显然可以合并在一起),所以对每个联通块分别判定其所有点的度数是否为偶数即可。
用并查集易维护,注意如果初始全为白就不操作。
丁香之路
i , j i,j i,j 之间的最短路是 ∣ i − j ∣ |i-j| ∣i−j∣,显然呐。
假设当前处理 i i i,问题相当于求一个 i i i 到 s s s 的欧拉路径。不妨把 i i i 与 s s s 连边,那么问题等价于从 i i i 出发的欧拉回路,注意 ( i , s ) (i,s) (i,s) 这条边不产生贡献。
考虑到欧拉图需满足如下两个性质:
- 对于 ∀ i , 2 ∣ d e g i \forall i,2 \mid deg_i ∀i,2∣degi
- 图联通
对于此题,我们先贪心的满足第一个性质(因为第二个性质难以入手啊)。
假设有一个点序列 { a 1 , a 2 , a 3 , . . . , a n } \{a_1,a_2,a_3,...,a_n\} {a1,a2,a3,...,an},满足 2 ∤ d e g a i 2 \nmid deg_{a_i} 2∤degai,我们很自然想到把 a 2 i a_{2i} a2i 与 a 2 i + 1 a_{2i+1} a2i+1 连边,因为度数总和为偶数,所以 a a a 的长度为偶数,这种贪心方法肯定是可行的,然而这种方法一定是最优的吗?
不一定,因为我们要保证图联通,所以在保证边权和不变的情况下,我们要尽可能的连边,因此我们把 a 2 i a_{2i} a2i 和 a 2 i + 1 a_{2i}+1 a2i+1 连边,一直连到 a 2 i + 1 − 1 a_{2i+1}-1 a2i+1−1 与 a 2 i + 1 a_{2i+1} a2i+1,这样相当于连了 a 2 i + 1 − a 2 i a_{2i+1}-a_{2i} a2i+1−a2i 条边权为 1 1 1 的边,然而却最大限度的促使了图联通。
满足第一个性质后,图仍有可能不连通,所以我们定义两个联通块之间的边权为分别从两个联通块中选出一个点的最小距离,跑一遍最小生成树,因为每个联通块都是一个欧拉图,所以合并起来后所有点的欧拉回路要加上 M S T × 2 MST \times 2 MST×2,这是显然的。
然而最坏情况下联通块的个数会达到 n n n,此时边的规模达到了 n 2 n^2 n2,无法接受。不难发现,我们贪心保证度数均为偶数后,联通块之间有一个相对顺序,举个例子,有三个联通块分别为 a , b , c a,b,c a,b,c,那么有 w ( a , c ) = w ( a , b ) + w ( b , c ) w(a,c)=w(a,b)+w(b,c) w(a,c)=w(a,b)+w(b,c),那么最终能成为最小生成树上的边只可能是相邻联通块之间的边。
此时边的规模缩减为 n n n,所以单次求解时间复杂度为 n log n n\log n nlogn,总时间复杂度为 O ( n 2 log n ) O(n^2\log n) O(n2logn),可以接受。
具体实现上,可以先把 m m m 条给定边的两端点 U n i o n S e t UnionSet UnionSet 起来,再进行后续操作。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通