[CF538E] Demiurges Play Again

Description

给定一棵有根树,甲乙轮流操作,每次每人选择一条边走,从根走到一个叶子,甲希望最后得到的叶子结点的权值尽可能大,乙希望最后得到的叶子结点的权值尽可能小,两人都采取最优策略。现在需要给每个叶子节点分配权值,权值是 (1 sim m) 的全排列。问让甲分配权值则最后取得的最大权值是多少,让乙分配权值则最后取得的最小权值是多少。

Solution

树形 dp,设 (f[i]) 表示 (i) 点子树内能达到的最小排名,(h[i]) 表示最大排名,则有

[f[i]=min_{i o j} h[j], h[i]=sum_{i o j} f[j] ]

#include <bits/stdc++.h>
using namespace std;


#define int long long
const int N = 1000005;

vector <int> g[N];

int n,m,t1,t2,f[N],h[N],vis[N];

void dfs(int p)
{
    vis[p]=1;
    f[p]=n+1;
    int fg=0;
    for(int q:g[p])
    {
        if(vis[q]==0)
        {
            fg=1;
            dfs(q);
            f[p]=min(f[p],h[q]);
            h[p]+=f[q];
        }
    }
    if(fg==0)
    {
        f[p]=h[p]=1;
        ++m;
    }
}

signed main()
{
    ios::sync_with_stdio(false);

    cin>>n;
    for(int i=1;i<n;i++)
    {
        cin>>t1>>t2;
        g[t1].push_back(t2);
        g[t2].push_back(t1);
    }
    dfs(1);

    cout<<m-f[1]+1<<" "<<h[1]<<endl;
}

原文地址:https://www.cnblogs.com/mollnn/p/13614480.html