CF538E
假设\(A\)为先手,即想要得到较大权值的人,\(B\)为后手。
令\(w(u)\)表示\(u\)子树中叶子的个数。假设某个非叶顶点\(u\)有子节点\(v_1,v_2,\cdots ,v_k\),并且在要在叶子上排列的数字为\(1,2,\cdots ,w(u)\)。当前并不能确定如何排列这些数字,但是假设现在已经知道关于子树中所需要的信息。
先考虑\(A\)如何移动能到达较大权值,显然他会选择最佳的子树,因此我们要将较大的数都放到\(A\)会选择的子树中,即:将\(A\)并不会走的子树中的较大的数与会走的子树中较小的数进行交换。考虑如果在\(v_i\)这个子树中放置\(w(v_i)\)个最大值(指\(w(u)-w(v_i)+1,\cdots ,w(u)\)),然后需要找出最佳的排列方案。这个任务本质与在\(u\)这棵子树中排列\(1,2,\ldots w(u)\)相同,但现在轮到\(B\)的回合。
令\(dp_{\max/ \min}(u)\)表示在\(u\)这棵子树中,轮到\(A\)或\(B\)行动时能获得的最大答案。通过前面的讨论可以得到转移
\[dp_\max \left(u\right)=\max\limits_{i=1}^k \left(w\left(u\right)-w\left(v_i \right)+dp_\min\left(v_i \right) \right)
\]
因此,假如已经知道所有\(v_i\)的\(dp_\min\),就可以求出\(dp_\max (u)\)。
然后考虑当轮到\(B\)先手时的情况。对于某个子树\(u\),假设将\(1\sim w(u)\)这些数字分别填入儿子的子树中。如果\(v_i\)子树中包含\(dp_{\max} (v_i)\)个数字,那么\(B\)就可以走到\(v_i\)。因此,对于每个\(i(i\in [1,k])\),可以将\(dp_{\max}(v_i)-1\)个数字放入\(v_i\)子树中(保证\(A\)拿不到)。因此可以得到转移:
\[dp_{\min}(u)=\sum _{i=1}^k \left(dp_{\max}\left(v_i\right)-1 \right)+1
\]
int w[222222],dp[222222][2];
vector<int>e[222222];
int n;
void dfs(int u)
{
if(e[u].size()==0) {w[u]=1;return;}
int mx=n+5;
for(int v:e[u])
{
dfs(v);
w[u]+=w[v];
ckmin(mx,dp[v][1]);
dp[u][1]+=w[v]-dp[v][0];
}
dp[u][1]--;
dp[u][0]=w[u]-mx-1;
}
signed main()
{
n=read();
int u,v;
R(i,2,n) u=read(),v=read(),e[u].pb(v);
dfs(1);
writesp(dp[1][0]+1),writeln(dp[1][1]+1);
}

浙公网安备 33010602011771号