http://codeforces.com/problemset/problem/533/B
题目大意:
每个人有一个直接的领导,1是总裁,现在要找一个最大的集合,每个领导领导的人的数量都是偶数,问最大的值是多少
思路:
dp:f[i][0]代表以i为根的子树,选出偶数个人的最大值,1反之。
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #include<cstring> 5 #include<iostream> 6 #define ll long long 7 ll f[200005][2],v[200005],ans; 8 int tot,go[200005],next[200005],first[200005]; 9 int n; 10 int read(){ 11 int t=0,f=1;char ch=getchar(); 12 while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();} 13 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 14 return t*f; 15 } 16 void insert(int x,int y){ 17 tot++; 18 go[tot]=y; 19 next[tot]=first[x]; 20 first[x]=tot; 21 } 22 void dfs(int x){ 23 f[x][1]=-0x3f3f3f3f; 24 f[x][0]=0; 25 int pd=0; 26 for (int i=first[x];i;i=next[i]){ 27 int pur=go[i]; 28 dfs(pur);pd=1; 29 ll t0=f[x][0],t1=f[x][1]; 30 f[x][0]=std::max(f[pur][0]+t0,f[pur][1]+t1); 31 f[x][1]=std::max(f[pur][0]+t1,f[pur][1]+t0); 32 } 33 if (!pd){ 34 f[x][1]=v[x]; 35 f[x][0]=0; 36 return; 37 } 38 f[x][1]=std::max(f[x][1],f[x][0]+v[x]); 39 } 40 int main(){ 41 n=read(); 42 for (int i=1;i<=n;i++){ 43 int x=read(),y=read(); 44 if (x!=-1) 45 insert(x,i); 46 v[i]=y; 47 } 48 dfs(1); 49 printf("%I64d ",f[1][1]); 50 return 0; 51 }