题意:给你一棵树,有三种规则
1)根节点不能选
2)选了这个点 它 的父亲节点和子节点都不能选。
3)一个点只能选其中的一个子节点。
问你选点的最大值
解题思路:树形DP。DP[I][1/0]表示选或不选最大的。
解题代码:
1 // File Name: c.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月21日 星期六 14时55分57秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 int dp[500005][2]; 28 vector<int> mp[500005]; 29 int hs[500005]; 30 int mxfrom[500005]; 31 void dfs(int k) 32 { 33 if(mp[k].size() == 0 ) 34 { 35 dp[k][1] = 1; 36 dp[k][0] = 0 ; 37 return ; 38 } 39 dp[k][1] = 1; 40 for(int i = 0 ;i < mp[k].size();i ++) 41 { 42 dfs(mp[k][i]); 43 dp[k][0] += dp[mp[k][i]][0]; 44 dp[k][1] += dp[mp[k][i]][0]; 45 } 46 int tt = dp[k][0]; 47 for(int i = 0 ;i < mp[k].size();i ++) 48 { 49 if(tt < dp[k][0] - dp[mp[k][i]][0] + dp[mp[k][i]][1]) 50 { 51 mxfrom[k] = mp[k][i]; 52 tt = dp[k][0] - dp[mp[k][i]][0] + dp[mp[k][i]][1]; 53 } 54 } 55 dp[k][0] = tt; 56 } 57 int tt; 58 int a[500005]; 59 void findans(int k,int v) 60 { 61 if(v == 1) 62 { 63 tt ++ ; 64 a[tt] = k ; 65 } 66 for(int i = 0 ;i < mp[k].size(); i ++) 67 { 68 if(mp[k][i] == mxfrom[k]) 69 findans(mp[k][i],1); 70 else 71 findans(mp[k][i],0); 72 } 73 } 74 int main(){ 75 freopen("grant.in","r",stdin); 76 freopen("grant.out","w",stdout); 77 int n; 78 scanf("%d",&n); 79 int tmp ; 80 for(int i= 2;i <= n;i ++) 81 { 82 scanf("%d",&tmp); 83 mp[tmp].push_back(i); 84 } 85 dfs(1); 86 printf("%d ",dp[1][0]*1000); 87 findans(1,0); 88 sort(a+1,a+1+tt); 89 for(int i = 1;i <= tt;i ++) 90 { 91 printf(i == 1?"%d":" %d",a[i]) ; 92 } 93 printf(" "); 94 return 0; 95 }