请先阅读图论学习笔记 1。
在这篇文章里,我们将继续以前 tarjan 求解的强连通分量和双连通分量,讲解其缩点相关内容。
也会讲解一些特殊的图:基环树与仙人掌图、最小树形图。
缩点
我们知道,将强连通分量、双连通分量缩点之后会形成一棵树。
在学术上,我们将边双连通分量缩点之后的树称为 Bridge Tree
,点双连通分量缩点之后的树称为 Block-Cut Tree
,强连通分量缩点之后的树称为 SCC DAG
。
缩点除了写法没什么好讲的,而且有一些已经在 图论学习笔记 1 中涉及到。就是将连通分量变成一个点,在相同连通分量中点之间的边隐藏,只保留连通分量之间的边。
先看题。
CF1000E We Need More Bosses
*2100,好像没多难。
题目大意:给定一个 \(n\) 点 \(m\) 边的连通无向图,需要找到两个点 \(s,t\),使得 \(s\) 到 \(t\) 必须要经过的边最多,即使 无论怎么走都会经过 的边最多。
我们很容易发现这东西和边双连通分量扯上了关系,因为边双连通分量的定义是:极大的,其中任意两个点之间至少有两条不重合的路径的连通子图。
显然,如果 \(s\) 到 \(t\) 在同一个边双连通分量内,它们必须要经过的边一定为 \(0\) 条。
从而我们可以得出,\(s\) 到 \(t\) 之间必须要经过的边,全部都是桥。
于是不妨想到对边双连通分量缩点。画图可以得到,必须要经过的边一定是 Bridge Tree
上面 \(s\) 和 \(t\) 处于的边双连通分量(假定为 \(x\) 和 \(y\))之间的路径。
于是问题变成了这样:给定一棵树,需要你求上面的最长路。
这不就是树的直径吗!当然这里可能有一些难写。
也有另一种做法:枚举 \(lca\) 的位置,显然 \(x\) 和 \(y\) 一定是在 \(lca\) 的子结点的不同的子树里面(要不然它们的 lca 就不是 \(lca\) 这个值了),设为 \(T_1\) 和 \(T_2\)。
要使路径长度最长,需要使 \(x\) 在 \(T_1\) 中深度最大的位置,\(y\) 也在 \(T_2\) 中深度最大的位置。
显然一个子树中的深度最大位置可以使用树形 dp来求,是基础中的基础了。
然后要算答案的时候,直接取子结点的子树最大深度 的 最大值和次大值 相加即可。
这道题就这么做完了,思维含量真的不高,*2100 可能是边双连通分量的加成。