杂题选讲 #2:广义串并联图
定义与性质
定义
什么是广义串并联图?
形式化地说,不存在同胚于
你可能不知道这是什么意思。通俗地说,就是不存在四个结点,满足其两两之间都有一条路径相连,且这些路径互不相交。
举例:树与仙人掌都是广义串并联图。
性质
广义串并联图有一系列的优秀性质:
- 广义串并联图是平面图;
- 广义串并联图可以通过以下的操作变成一个单点:
- 删一度点(去断路):选择一个度数为
1 的点并删掉它和与它连接的边; - 缩二度点(消串联):选择一个度数为
2 的点,用一条边替换它和与它相连的两条边(你可以理解为把它与连接它的两条边“缩”成一条边); - 叠合重边(消并联):选择两条重边,用一条边替换它们;
- 删一度点(去断路):选择一个度数为
- 广义串并联图在进行上述操作中,每一条边都对应原图的一个子图。
- 上面的三种操作在一般图中的体现称为“广义串并联图方法”。对于一般图
G=(V,E) ,令n=|V| ,m=|E| ,如果满足m-n\le k ,其中k 很小,那么运用广义串并联图方法对图进行操作可以使原图满足n\le 2k ,m\le 3k ,然后一些题可以直接暴力做。证明考虑三种操作中m-n 的值都不增,并且因为不能进行操作时已经满足每个点的度数都大于3 ,所以3n\le 2m ,于是n\le 2k ,m\le 3k 。
值得注意的是,对广义串并联图的操作不是白做的。在进行操作时,由于图的形态发生改变,点 / 边上记录的值(就是各种贡献)可能会发生改变。
广义串并联图的题目通常的难点在于探究对于每种操作前后贡献的变化;接下来我们将用实例说明操作对贡献的影响可能是什么样的。
[SNOI2020] 生成树
题意简述
给定一个图,保证该图删掉一条边后是仙人掌。求该图的生成树个数。答案对
数据范围:
题目信息
来源:陕西省 NOI 省队选拔赛 2020 D1T1
难度:
提示
或许你忘了什么是仙人掌;仙人掌是不存在两个拥有公共边的简单环的无向连通图。
解法
如果数据范围比较小可以矩阵树定理直接暴做,但是这题可能连
观察到原图是广义串并联图。考虑原图为什么是广义串并联图:先考虑一个仙人掌,从中取出
怎么用广义串并联图方法?
将贡献缩到边上面(前面说过一条边代表一个子图),一条边
令一条边
- 删一度点(去断路):令一度点连接的唯一一条边为
e ,执行s\gets s\cdot f(e) ,然后删掉这个点以及与它相连的边; - 缩二度点(消串联):令二度点连接的两条边分别为
e_1 ,e_2 ,操作之后的边为e' ,则有f(e')=f(e_1)\cdot f(e_2) ,g(e')=f(e_1)\cdot g(e_2)+f(e_2)\cdot g(e_1) ; - 叠合重边(消并联):令两条重边分别为
e_1 ,e_2 ,操作之后的边为e' ,则有g(e')=g(e_1)\cdot g(e_2) ,f(e')=f(e_1)\cdot g(e_2)+f(e_2)\cdot g(e_1) ;
那么,如何具体实现上述的操作?
对于每条边,开一个结构体记录两端点以及 std::set 存边,这样便于删边。
用队列模拟操作过程,每次把满足条件的一度点与二度点扔进去。重边在输入的时候就提前都叠起来,广搜的时候就不用处理重边了。
参考代码(C++17):
提交记录 #354414 - QOJ.ac
练习题 & 总结
该类型的习题较多,这里推荐几道比较经典的:
- [JOI Open 2022] 放学路 - 洛谷 | 计算机科学教育新生态
- 「2019 集训队互测 Day 3」公园 – LibreOJ
- Codeforces 1656I Neighbour Ordering(难度很高)
在 OI 中比较常用的是广义串并联图方法,只需牢牢记住三种操作“删一度点”“缩二度点”“叠合重边”,即“去断路”“消串联”“消并联”,并且能较好地计算操作中贡献的变化,就可以解决大部分的相关问题。