题解:P11593 [NordicOI 2024] Thin Ice
拿金币的后效性太大了,我们完全分析不出一个保证最优的贪心策略。如果你做过 [ARC098F] Donation 或者偶然注意到了样例分析中 Uolevi 不可能收集到大于 6 个金币,因为边缘所有格子的承受能力都小于等于 5 这句话,你就会想到倒推。
我们假设最后有
你发现答案可以二分了。二分完
此时我们需要知道,冰面上的移动并非无迹可寻,令相邻的两个格子
因此我们在二分内层对 kruskal 重构树进行 DP,设
如果
DP 部分:
int lim[N * 2], f[N * 2], siz[N * 2], ls[N * 2], rs[N * 2];
inline void treedp(int pos, int x)
{
if(is[pos] && x <= lim[pos]) f[pos] = x - 1;
if(ls[pos] && rs[pos])
{
treedp(ls[pos], x), treedp(rs[pos], x);
siz[pos] = siz[ls[pos]] + siz[rs[pos]];
if(f[ls[pos]] <= lim[pos]) f[pos] = min(f[pos], f[ls[pos]] - (siz[pos] - siz[ls[pos]]));
if(f[rs[pos]] <= lim[pos]) f[pos] = min(f[pos], f[rs[pos]] - (siz[pos] - siz[rs[pos]]));
}
else siz[pos] = 1;
}
inline bool check(int x)
{
memset(f, 0x3f, sizeof(f));
memset(siz, 0, sizeof(siz));
treedp(dsu.idx, x);
return (f[dsu.idx] <= 0);
}