前言
做一下一场没打的 \(\textrm{div 2}\) 的 \(\rm{C}\)
最近思维能力还在下降, 无敌
前天还能打出思维题, 今天打不出 \(\textrm{div 2 C}\)
思路
首先转化题意
给定一个 \(n\) 节点的树, 求删除两个节点及其连边之后, 最大连通块的数量
不难发现删除一个节点, 会把树分成几个部分, 由其出边条数确定
但是删除两个节点略有不同
容易想到的是贪心的切两次
考虑是否能够找到反例
容易发现大小为 \(4\) 的菊花图或者
都可以卡掉贪心做法
考虑贪心做法为什么是错的, 一般来说, 都是因为删除了一个点使得浪费了其他点的出边
所以现在问题简单化成了如何找到两个点, 使关于两个点的边数最大
方法 \(1\)
这个问题可以考虑树形 \(\rm{dp}\) , 因为边的重合不具有传递性或者后效性, 可以直接做
令 \(f_{u, 0/1/2, 0/1}\) 表示 \(u\) 子树, 删了多少个点, 其中 \(u\) 点是否被删除的最大联通块个数
考虑转移
初始化 \(f_{\textrm{leaves}, 0, 0} = 1, f_{\textrm{leaves}, 1, 1} = 0\)
转移不说了, 不难想到
方法 \(2\)
你发现可以不用这么高级, 直接 \(\rm{multiset}\) 维护删除每一个点之后余下点的度数, 不难发现是 \(\mathcal{O} (n \log n)\) 的
总结
善于找到问题的本质
这种树上问题可以考虑 \(\rm{dp}\) , 但是注意状态一定要能转移
然后就是之前做过的树上合并的问题了