Codeforces Round #300 E - Demiurges Play Again

E - Demiurges Play Again

感觉这种类型的dp以前没遇到过。。。 不是很好想。。

dp[u] 表示的是以u为子树进行游戏得到的值是第几大的。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define y1 skldjfskldjg
#define y2 skldfjsklejg

using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;

int n, sum[N], dp[N], f[N], dp2[N];
vector<int> edge[N];

void dfs(int u, int fa) {
    for(int v : edge[u]) {
        if(v == fa) continue;
        f[u] = true;
        dfs(v, u);
        sum[u] += sum[v];
    }
    sum[u] += !f[u];
}

void dfs2(int u, int fa, int depth) {
    if(!f[u]) {
        dp[u] = 1;
        dp2[u] = 1;
        return;
    }
    if(depth & 1) {
        dp2[u] = inf;
        for(int v : edge[u]) {
            if(v == fa) continue;
            dfs2(v, u, depth + 1);
            dp[u] += dp[v];
            dp2[u] = min(dp2[u], dp2[v]);
        }
    } else {
        dp[u] = inf;
        for(int v : edge[u]) {
            if(v == fa) continue;
            dfs2(v, u, depth + 1);
            dp[u] = min(dp[u], dp[v]);
            dp2[u] += dp2[v];
        }
    }
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i < n; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        edge[u].push_back(v);
        edge[v].push_back(u);
    }
    dfs(1, 0);
    dfs2(1, 0, 0);
    printf("%d %d\n", sum[1] - dp[1] + 1, dp2[1]);
    return 0;
}

/*
5
1 5 4 3 2
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9671050.html