题目来自: 2021 ICPC Southeastern Europe Regional Contest
C - Werewolves
给出$n(n \le 3000)$个点的一棵树, 以及每个点的颜色, 求满足拥有一半以上同种颜色的连通块的个数, 对$998244353$取模
首先对一种特定颜色$c$考虑, 如果一个点的颜色是$c$就$+1$, 不是就$-1$, 那么最后只要这个连通块的权值大于$0$, 就可以记入答案中.
那么我们可以考虑树上背包, 用$dp[u][j]$表示$u$点必取时连通块权值为$j$的数量.
然后就可以推出转移式是: $dp[u][k] = dp[u][k - j] * dp[v][j]$
由于可能出现负的权值, 可以给第二维整体加上一个值来避免出现负值
众所周知,一棵$n$点的树, 背包容量为$m$, 进行树上背包时如果上下界都卡紧了复杂度会是$O(nm)$ 具体证明可以看这个
那么在这个问题里, 对特定颜色考虑时, 背包容量最大是$c_i$(颜色为$c$的点的个数), 所以单次背包的时间复杂度是$O(nc_i)$
所以对每种颜色都跑一遍的复杂度就是$O(n\sum c_i)$, 由于$\sum c_i = n$, 所以总复杂度为$O(n ^ 2)$
1 |
|
K - Amazing Tree
给出一棵树, 让你选择一个根使以这个根节点开始的先序遍历的字典序是最小的
无论选哪个点为根, 先序遍历的第一个值肯定是某一个叶子结点.
那么第一个值肯定是所有叶子结点中最小的那一个, 然后考虑与它相连的$v$点, 如果除去最小的叶子结点外与$v$结点直接相连的还有两个及以上的点, 那么根据先序遍历的顺序, 之后还会往$v$结点的儿子结点遍历. 这个时候可以考虑贪心, 优先向有更小编号的叶子结点的点方向遍历. 当与$v$结点相连的点只剩一个的时候, 此时$v$点有两种可能, $v$是根节点或不是, 若它不是根节点, 那么下一个遍历的点就是它自己. 如果$v$是根节点, 那么就会先向它最后一个儿子结点处先遍历, 然后最后才遍历$v$.
于是只需要贪心的选择小的就行了, 如果$v$比最后一个儿子结点处的叶子结点编号小, 那么$v$就不是根节点, 继续往下$dfs$找根, 反之根节点就确定了, 停止$dfs$直接输出答案
1 |
|