题解:CF858F Wizard's Tour
LinkCatTree · · 题解
题意即为:找出最多的端点相交的边二元组且不得重复使用边。
类似的构造问题都可以尝试考虑 dfs 生成树。
手玩一下我们发现:对于一个包含
我们声称,一定存在一种构造方式,对于 dfs 树上
u 的子树,其中所有树边和两端都在子树中的返祖边都能被两两配对,至多剩下一条一端为u 的边。
考虑归纳证明这个结论。
我们考虑点
再考虑所有
构造部分代码:
int dfs (int u, int fa) {
dfn [u] = ++tim;
vector <int> vets;
for (const int v : edg [u]) {
if (v == fa)
continue ;
if (dfn [v] && dfn [v] > dfn [u])
vets.emplace_back (v);
else if (!dfn [v]) {
int k = dfs (v, u);
if (k)
ans.emplace_back (u, v, k);
else
vets.emplace_back (v);
}
}
for (int i = 0; i + 1 < (int) vets.size (); i += 2)
ans.emplace_back (vets [i], u, vets [i + 1]);
return ((int) vets.size () & 1) ? vets.back () : 0;
}