虚树
定义
对于一棵树 \(T(S, E)\),取出一个点集 \(T \subseteq S\) 作为关键点集,将关键点和它们两两的 LCA 取出构成一个点集 \(V'\) 建一棵树,即为虚树。
建树
- 将 \(S\) 中所有点按 DFS 序排序,把所有相邻项的 LCA 再求出来放入序列 \(A\)。根据 DFS 序的性质,此时将 \(A\) 去重就得到了虚树的点集。
- 然后将序列 \(A\) 排序,对 \(A\) 中所有 \((A_i, A_{i+1})\),将它们的 LCA 记录为父亲节点即可。
inline bool cmp(int x, int y)
{
return dfn[x] < dfn[y]; // 按照 dfs 序排序
}
void build_virtual_tree()
{
sort(h + 1, h + m + 1, cmp); // 把关键点按照 dfs 序排序
for(int i = 1; i < m; i++){
a[++len] = h[i];
a[++len] = lca(h[i], h[i + 1]); // 插入 lca
}
a[++len] = h[m];
sort(a + 1, a + len + 1, cmp); // 把所有虚树上的点按照 dfs 序排序
len = unique(a + 1, a + len + 1) - a - 1; // 去重
for(int i = 1, lc; i < len; ++i) {
lc = lca(a[i], a[i + 1]);
fa[a[i]] = fa[a[i + 1]] = lc;
}
}
望穿寂夜晨曦至,雄鹰展翅图九天。

浙公网安备 33010602011771号