洛谷P2996 [USACO10NOV]拜访奶牛Visiting Cows
树形dp
设f[i][j]表示走到第i号节点的最大权值
j为0/1表示这个点选或者不选
如果这个点不选 就从他的子树里的选或者不选选最大
如果这个点选 就加上他子树的不选
f[x][0] += max(f[to][1], f[to][0]);
f[x][1] += f[to][0];
注意第二维要开到2
Code:
//设f[i][j]表示选到第i号节点的最大权值 #include <cstdio> #include <iostream> using namespace std; const int N = 500010; int f[N][2], n, head[N << 1], cnt; struct node { int nxt, to; }e[N]; int read() { int s = 0, w = 1; char ch = getchar(); while(!isdigit(ch)) {if(ch == '-') w = -1; ch = getchar();} while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();} return s * w; } void add(int x, int y) { e[++cnt].nxt = head[x]; e[cnt].to = y; head[x] = cnt; } void dfs(int x, int fa) { f[x][1] = 1; for(int i = head[x]; i; i = e[i].nxt) { int v = e[i].to; if(v != fa) { dfs(v, x); f[x][0] += max(f[v][0], f[v][1]); f[x][1] += f[v][0]; } } } int main() { n = read(); for(int i = 1, x, y; i < n; i++) { x = read(), y = read(); add(x, y), add(y, x); } dfs(1, 0); cout << max(f[1][1], f[1][0]) << endl; return 0; }