树形DP,还是求最大独立集,加上判断唯一性,这题我就卡在唯一性上了。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define N 205
 4 int fst[N],nxt[N],v[N],n,m;
 5 int only[N][2],dp[N][2];
 6 char name[N][105];
 7 int max(int a, int b)
 8 {
 9     return a>b ?a :b;
10 }
11 int find(char *t)
12 {
13     for(int i = 0; i < m; i++)
14         if(!strcmp(name[i],t))
15             return i;
16     return -1;
17 }
18 void dfs(int u)
19 {
20     int e,i;
21     dp[u][0] = 0;
22     dp[u][1] = 1;
23     only[u][0] = only[u][1] = 1;
24     for(i = fst[u]; i != -1; i = nxt[i])
25     {
26         e = v[i];
27         dfs(e);
28         dp[u][0] += max(dp[e][0],dp[e][1]);
29         if(dp[e][0]==dp[e][1]) only[u][0] = 0;
30         else if((dp[e][0] > dp[e][1]) && only[u][0])
31             only[u][0] = only[e][0];
32         else if(only[u][0])
33             only[u][0] = only[e][1];
34         dp[u][1] += dp[e][0];
35         if(only[u][1]) only[u][1] = only[e][0];
36     }
37     //printf("dp[%d][0]: %d\ndp[%d][1]: %d\n",u,dp[u][0],u,dp[u][1]);
38 }
39 int main()
40 {
41     int i,u;
42     char s[105],t[105];
43     while(scanf("%d",&n),n)
44     {
45         memset(fst,-1,sizeof fst);
46         scanf("%s",name[0]);
47         for(i = m = 1; i < n; i++)
48         {
49             scanf("%s %s",s,t);
50             u = find(t);
51             v[i] = find(s);
52             if(u == -1)
53                 u = m, strcpy(name[m++],t);
54             if(v[i] == -1)
55                 v[i] = m, strcpy(name[m++],s);
56             nxt[i] = fst[u];
57             fst[u] = i;
58         }
59         dfs(0);
60         if(dp[0][0] > dp[0][1])
61         {
62             printf("%d ",dp[0][0]);
63             printf(only[0][0] ?"Yes\n" :"No\n");
64         }
65         else if(dp[0][0] < dp[0][1])
66         {
67             printf("%d ",dp[0][1]);
68             printf(only[0][1] ?"Yes\n" :"No\n");
69         }
70         else
71             printf("%d No\n",dp[0][1]);
72     }
73     return 0;
74 }