hdu 2412 树形dp
1 /* 2 题目大意:一个n个节点的树,求选取一些节点(不能含有父子关系的)的最大数量,且是否唯一。 3 dp(i,0)表示当前节点i不选,dp(i,1)表示当前节点i选 4 叶子节点dp(i,0)=0,dp(i,1)=1 5 dp(i,0)=sigma(max(dp(j,0),dp(j,1))) (j是i的儿子) 6 dp(i,1)=sigma(dp(j,0))+1(j是i的儿子) 7 最多人数为max(dp(0,0),dp(0,1))(0表示根节点) 8 用flag数组标记结果是否唯一 9 对于叶子结点, flag[k][0]=flag[k][1] = 1. 10 对于非叶子结点, 11 不选i,对于i的任一儿子j, 12 若(dp[j][0] > dp[j][1] 且 flag[j][0] == 0) 或 (dp[j][0] < dp[j][1] 且 flag[j][1] == 0) 或 (dp[j][0] == dp[j][1]), 13 则flag[i][0] = 0 14 选i,对于i的任一儿子j有flag[j][0] = 0, 15 则flag[i][1] = 0 16 */ 17 #pragma warning (disable:4786) 18 #include <iostream> 19 #include <cstring> 20 #include <cstdio> 21 #include <string> 22 #include <map> 23 #include <vector> 24 using namespace std; 25 26 const int maxn=205; 27 vector<int> f[maxn];//关系图 28 bool flag[maxn][2];//标记是否唯一 29 map<string,int> m;//名字与节点标号映射 30 int dp[maxn][2]; 31 inline int max(int a,int b){return a>b?a:b;} 32 33 void dfs(int id) 34 { 35 if(f[id].size()==0) 36 { 37 dp[id][0]=0;dp[id][1]=1; 38 return ; 39 } 40 int i,sum1=0,sum2=0; 41 for(i=0;i<f[id].size();i++) 42 { 43 dfs(f[id][i]); 44 sum1+=max(dp[f[id][i]][0],dp[f[id][i]][1]); 45 sum2+=dp[f[id][i]][0]; 46 if((dp[f[id][i]][0]>dp[f[id][i]][1] && flag[f[id][i]][0]==0) 47 || (dp[f[id][i]][0]<dp[f[id][i]][1] && flag[f[id][i]][1]==0) 48 || dp[f[id][i]][0]==dp[f[id][i]][1]) 49 flag[id][0]=0; 50 if(flag[f[id][i]][0]==0) 51 flag[id][1]=0; 52 } 53 dp[id][0]=sum1;dp[id][1]=sum2+1; 54 return ; 55 } 56 int main() 57 { 58 int i,n,cnt; 59 string name1,name2; 60 while(scanf("%d",&n),n) 61 { 62 for(i=1;i<maxn;i++) f[i].clear(); 63 m.clear(); 64 cnt=0; 65 cin>>name1;m[name1]=++cnt; 66 for(i=2;i<=n;i++) 67 { 68 cin>>name1>>name2; 69 if(m.find(name1)==m.end()) 70 m[name1]=++cnt; 71 if(m.find(name2)==m.end()) 72 m[name2]=++cnt; 73 f[m[name2]].push_back(m[name1]); 74 } 75 memset(flag,1,sizeof(flag)); 76 dfs(1); 77 int ans=max(dp[1][0],dp[1][1]); 78 printf("%d ",ans); 79 if(dp[1][0]==dp[1][1] || (dp[1][0]>dp[1][1] && flag[1][0]==0) || (dp[1][0]<dp[1][1] && flag[1][1]==0)) 80 printf("No\n"); 81 else printf("Yes\n"); 82 } 83 return 0; 84 }