虚树学习笔记
Butterfly_qwq · · 算法·理论
有一个
对于
保证给定的
注:
朴素想法树形DP,在此略过
如何优化?
我们可以发现有许多点是无用的
注:没有
显然简化了不少。
那如何构造这样一颗树呢?
- 所有关键点以dfn排序
- 两两求出LCA
- 将所有LCA和点1插入虚树的点数组,然后按dfn排序后去重
- 再次两两求LCA,将两个点中dfn较大的点与求出来的LCA连线
做完了
Code:
bool cmp(int x, int y) {//按照 dfn 序排序
return dfn[x] < dfn[y];
}
void build() {
int len=0;
sort(h + 1, h + k + 1, cmp); //输入的关键点
for(int i = 1; i < k; i++) {
a[++len] = h[i];
a[++len] = lca(h[i], h[i + 1]); //插入 lca
}
a[++len] = h[k]; a[++len] = 1;
sort(a + 1, a + len + 1, cmp); //把所有虚树上的点按照 dfn 序排序
len = unique(a + 1, a + len + 1) - a - 1; //去重
for (int i = 1, lc; i < len; i++) {
lc = lca(a[i], a[i + 1]);
add(lc, a[i + 1]); //连边
}
}
注:不是我写的,但是有错还是找我的洛谷账号 @FeS2_qwq(或直接联系@babyec 虽然我很不建议你这样干)
但是,别忘了我们还有边权!!!新边权怎么办?
别着急,我们有只用老边权处理新图的方案。
设
否则,则
注:
哦,漏了一点,时间复杂度
然后大概就做完了吧。
模板题
纯纯的模板啊!!!
该文同步发表于