[BZOJ2060/Luogu2996][USACO10NOV]拜访奶牛Visiting Cows
题目链接:
简单的树形DP。
设\(f[x][0/1]\)表示在以\(x\)为根的子树内选/不选\(x\)的最大答案。
有转移:
\(f[x][0]=\sum max(f[y][0],f[y][1])\)
\(f[x][1]=1+\sum f[y][0]\)
时间复杂度 \(O(n)\)
代码:
#include <cstdio>
#include <vector>
#include <algorithm>
int n,f[50005][2];
std::vector<int> g[50005];
void DP(const int x,const int Pre)
{
f[x][1]=1;
for(int i=0,y;i<(int)g[x].size();++i)
if((y=g[x][i])!=Pre)
{
DP(y,x);
f[x][0]+=std::max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}
int main()
{
scanf("%d",&n);
for(int i=1,x,y;i<n;++i)
{
scanf("%d%d",&x,&y);
g[x].push_back(y);
g[y].push_back(x);
}
DP(1,0),printf("%d\n",std::max(f[1][0],f[1][1]));
return 0;
}