CF1928G Vlad and Trouble at MIT
Problem
MIT的学生宿舍可以用一棵有\(n\)个顶点的树来表示,每个顶点代表一个房间,每个房间一个学生。
今晚,有三种类型的学生:
- 想参加派对和玩音乐的学生(标记为 \(\texttt{P}\) )
- 想睡觉和享受安静的学生(标记为 \(\texttt{S}\) )
- 无所谓的学生(标记为 \(\texttt{C}\) )。
开始时所有的边缘都是薄墙,允许音乐通过,因此当参加派对的学生放音乐时,每个房间都能听到。但是,我们可以在任何边缘放置一些厚墙--厚墙不允许音乐通过。
学校希望安装一些厚墙,这样每个参加派对的学生都可以播放音乐,而睡觉的学生却听不到。
最少需要多少厚墙?
\(1 \leq t \leq 1000\)
\(2 \leq \sum n \leq 10^5\)
Wrong Solution
选择最少条边,将所有的P和S隔开。此时C是无所谓的。
如果这张图里面没有C,只有P和S的话,那么这棵树就是将将所有P-S边封上即可;
假如有C呢?我先想到了贪心+给C-C缩成一个C。结果缩点都写完了,突然发觉这贪心是伪的(也许有真的贪心吧)
Solution
树型dp。
任选一个节点作为根节点。设dp[i]
表示以i
为根节点的子树目前是被谁占领的(1
表示P
,2表示S
,3表示无所谓)
dfs这棵树,先到叶子节点,叶子节点的占领情况自然就是这一节点本身的值。
回溯到点x
,分为几种情况:
节点本身为
C
,即无所谓。 此时需要考虑各个子树之间的互相影响。 统计子树的dp
,看看各个子树目前的占领情况。若子树中
P
与S
一样多那么让
P
占领自身与让S
占领自身的花费都是一样的。所以设dp[x]
为0,即无所谓。(由上游摆布)若子树中
P
与S
不一样多优先给数量少的子树封上硬墙,并且点x被数量多的那种占领。
节点本身不为
C
。那么点x自然只能被其本身的学生类型所占领。
并且所有与之互斥的子树都需要加墙,无所谓的子树则不用
时间复杂度\(O(tn)\)
Code
1 |
|
Referance
CJQ