【2020.11.30提高组模拟】关灯(light)
原题:「COCI 2020.11」Svjetlo
LOJ链接:[#3385. 「COCI 2020.11」Svjetlo - 题目 - LibreOJ (loj.ac)]
简要题意
给一棵大小为n的树,从任意点出发沿着边走,规定一个节点只能到达奇数或偶数次,求路径最小长度
题解
容易想到DP
f [ x ] [ 0 / 1 ] f[x][0/1] f[x][0/1]表示以x为根的子树中除自己以外全部点都做完了,自身状态为0/1,且起/终点不在该子树内
g [ x ] [ 0 / 1 ] g[x][0/1] g[x][0/1]表示以x为根的子树中除自己以外全部点都做完了,自身状态为0/1,且起/终点有一个在该子树内
h [ x ] [ 0 / 1 ] h[x][0/1] h[x][0/1]表示以x为根的子树中除自己以外全部点都做完了,自身状态为0/1,且起/终点都在该子树内
- 其实起点和终点是一样的,所以这么设g
- 这里强制要求要走到点x
- 对于f起点即为x,但是不会让x出现在序列中(即不算贡献)
(可能这里的设定有些诡异,但是没看懂没关系)
对于一棵子树比如这样:
那么f,g,h代表意义大概即为这样:
注意到因为可能还可以往上走,所以可能是断开的
发现可以在x和某子树s的连边上做DP,仅仅算经过这条边的贡献
自然直接DFS,对于点x每次进入一个儿子s做完DP之后就更新x的DP值,表示进入s逛了一圈
**注意!!!**做完s之后就再也不会回到s了,因此要保证s的状态正确,假如发现不对就直接反复横跳一次(贡献+2),同时改变s和x的状态
那么就开始愉快的转移啦~
-
首先是f:
显然只能由之前的 f [ x ] f[x] f[x]和 f [ s ] f[s] f[s]合起来
一步下去+一步上来=>贡献+2
-
然后是g:
可能由之前的 g [ x ] g[x] g[x]和 f [ s ] f[s] f[s]合起来
一步下去+一步上来=>贡献+2
也可能指由之前的 f [ x ] f[x] f[x]和 g [ s ] g[s] g[s]合起来
**注意!!!**假设这个g是起点,所以这里只需一步上来=>贡献+1
-
最后是h:
可能由之前的 h [ x ] h[x] h[x]和 f [ s ] f[s] f[s]合起来
一步下去+一步上来=>贡献+2
也可能指由之前的 f [ x ] f[x] f[x]和 h [ s ] h[s] h[s]