首页 > 代码库 > 【Luogu2996】拜访奶牛

【Luogu2996】拜访奶牛

点此进入原题

算法树形DP

题解

一道树形dp。由题意可知,这题是树形结构题。我们设f[i][0],表示不访问i号节点,f[i][1]表示访问i号节点。因为访问了i号节点,则不能访问i的孩子节点,所以可以得出下面的式子:

f[i][0] += max{f[k][0], f[k][1]}

f[i][1] += f[k][0] + 1

(f[i][0]=0, f[i][1]=1, k是i的孩子)

可以用邻接表存储。同时要注意孩子不能返回访问父亲。

代码

#include <cstdio>
const int N = 50005;
int head[N], next[2*N], adj[2*N], tot, n, f[N][2];
inline int mx(int x, int y) {
    return x > y ? x : y;
}
void addedge (int u, int v) {
    next[++tot] = head[u];
    head[u] = tot;
    adj[tot] = v;
}
void dfs(int u, int father) {
    f[u][1] = 1;
    for(int e = head[u]; e; e = next[e]) {
        if(adj[e] == father) continue;
        dfs(adj[e], u);
        f[u][0] += mx(f[adj[e]][0], f[adj[e]][1]);
        f[u][1] += f[adj[e]][0];
    }
}
int main() {
    scanf("%d", &n);
    for(int i = 1, u, v; i < n; i++) {
        scanf("%d%d", &u, &v);
        addedge(u, v);
        addedge(v, u);
    }
    dfs(1, 0);
    printf("%d", mx(f[1][0], f[1][1]));
    return 0;
}

 

【Luogu2996】拜访奶牛