DFS 树
dfs 树就是 dfs 生成的树。
性质:没有横叉边。
所有叶子构成原图的独立集,因为叶子之间没有横叉边。
同深度的点也能构成独立集,这跟上面类似。
CF1470D Strange Housing
这道题就是 dfs 树的性质应用(其实没有利用任何性质)
给一个无向图。求一个独立集,使得只保留和独立集相连的边,图仍然连通。
这道题我们按照 dfs 的顺序选,能选就选。
证明就用归纳法,对于每一个 都能保证做完这个操作后连通。
P5811 [IOI 2019] 景点划分
主要思想:拆分化简问题。
考虑树的特殊情况,然后处理 dfs 树的返祖边
首先,为了让问题更简单,需要钦定变量顺序,我们设 ,然后需要满足 和 即可,因为我们如果选了 ,可以通过拆分 来得到 或者 ,所以只弄 和 是最优的。
然后我们发现这个图有点复杂了,于是我们先考虑树的情况,我们发现我们需要让树存在一条边,切掉之后左边大小 ,右边 ,即存在 的子树。
然后由于 ,所以我们想到了重心。我们先找到重心,然后,如果有解一定存在一个子树大小大于等于 ,然后剩下的拆成 就行了。
然后树的情况就做完了,我们想想图怎么做。
我们先建出 dfs 树,然后找出重心(类比刚才的特殊情况)。如果存在一个子树大小 就直接可行,否则我们需要考虑返祖边。
考虑返祖边就是看这个子树中的节点连接到的重心的祖先。具体写法就是直接向上,然后限制不能走重心。
以重心为根,每个子树(块)大小 。利用返祖边(连接重心祖先和重心儿子),可将多个子树连通。依次累加子树大小直至总和 ,将这些子树与重心一同作为 ,则 (因每个子树 ,累加刚达 时总和 )。
证明:由 得 。剩余部分点数 ,且原图连通,故剩余点中必有一连通块大小 ,取为 。
所以那个 的限制也限制了 和 的量级,从而更好地找到子集。
CF51F Caterpillar
性质结论题
首先,我们发现毛毛虫不能有环,所以先缩环。然后就变成了一个树上问题。
这时候,我们会猜结论:选直径!
怎么证明?我们模拟一下过程,就会发现叶子节点是不会合并的,直接合并父节点就行了。所以我们需要保留最多的父节点,于是就选直径了。
P3225 [HNOI2012] 矿场搭建
Tarjan 的应用
首先这道题肯定和割点有关。
对于每一个点双,我们发现,如果这个点双连接了两个及以上割点,都可以跑到别的点双里面。
然后否则就在这个点双中建立一个逃生点。方案数 。
然后如果没有割点,就是独立的,需要两个救生点,所以就是 。
注意写法
if(low[v]>=dfn[x]){
g[x]=1;
child++;
dcc++;
while(s.top()!=v){
d[dcc].push_back(s.top());
s.pop();
}
// d[dcc].push_back(x);
d[dcc].push_back(s.top());
s.pop();
d[dcc].push_back(x);
}
需要这样写,因为每一个 可能在不同强连通分量中。
圆方树
实在懒得讲了,反正大体思路还好,就放点例题吧。
P4630 [APIO2018] 铁人两项
圆方树的应用
注意:两个点也要算作点双。
首先,对于每一个 和 ,我们的答案就是两点的所有路径中的点的并集大小减二。
然后我们想到这个问题在树上更方便求解,于是我们需要圆方树。
此时我们可以把方点设为这个点双的大小。但是这时候我们发现,方点之间会有共同的节点,也就是割点,所以我们需要将路径中的圆点的权值设成 ,然后路径中的权值和就是路径的节点个数了。
令 为点权,对于节点 ,两个点都在子树中的情况:
然后我们发现这会有很多的重复的,就利用刚刚的点权进行容斥:
这样就能避免割点被重复统计。
还有就是这三个点互不相同,由于方点,会重复计算,所以直接在圆点就抵消掉。
CF1763F Edge Queries
圆方树简单应用
建出圆方树可以直接做,用 表示非割边的前缀和。
P4606 [SDOI2018] 战略游戏
有一个经典 trick:
- 树的 dfs 序求出后,假设按 dfn 排序后关键点序列为 。所有关键点形成的极小连通子树边权和的两倍为 。
圆方树应用+虚树思想
将原图转化为圆方树(原图中的点为圆点,每个点双连通分量建一个方点)。
在圆方树上,圆点权值为 ,方点权值为 ,并将点权转化为到父节点的边权(便于路径求和)。
对于每个询问的点集 ,将其按 DFS 序排序,计算相邻点(包括首尾)在树上的路径权值和,总和除以 得到包含所有 的最小连通子图的边权和。
这里不建出虚树了,就用虚树的思想。
加上该子图根节点(即排序后第一个与最后一个点的 LCA)的权值,得到子图中所有点的权值和,即圆点总数。
减去 即得到不在 中且删除后能使 不连通的圆点数量。
一个写法:记录路径权值不算 的,只有进入和出去会计算 。然后对于节点 就单独算了。
P8456 「SWTR-8」地地铁铁
这道题首先我们发现如果有环就可以选择任意一个方向。
所以我们想到,先建出圆方树。
- 对于在同一个方点的情况:
- 如果全是一个字母,答案就是 。
- 答案是 ,但是又有一种情况就是如果这个点从两边走,两边的路径上的点一边全是 一边全是 需要减去 。
- 其他情况类似:
- 对于普通的情况,如果一条路径同时存在白点双或黑点双,这一定可以。特殊的那种左边只有 ,右边只有 的一定可以有一种让两点混的方式。
至于写法,就需要好好想想了,不然代码会很长。这里的一边全是 一边全是 这种情况直接判断哪个有 和 的入度的个数 即可。