Party at Hali-Bula(树形DP+判断方案数是否唯一)
Party at Hali-Bula
题意:
公司里有n(n<=200)个人形成一个树状结构, 要求尽量选多的人,但不能同时选择一个人和他的直属上司,文最多能选多少人,以及是否方案唯一。
1 //dp[x][0]表示不选X节点能达到的最大人数,dp[x][1]表示选x节点的最大人数
2 //f数组含义和dp基本一致,f[x][0]表示如果不选x节点是否方案数唯一 f[x][1]表示如果选x节点方案数是否唯一
3 //如果f数组为1表示方案数不唯一
4 //对于一个根节点,如果其子节点中有一个方案数不唯一则其方案数不唯一
5
6 #include<iostream>
7 #include<cstdio>
8 #include<cstring>
9 #include<map>
10 #include<vector>
11 #include<algorithm>
12 using namespace std;
13 vector<int>v[500];
14 string s1,s2;
15 map<string,int>mp;
16 int n;
17 int flag;
18 int dp[500][500];
19 int f[500][500];
20 int vis[500];
21 void dfs(int x)
22 {
23
24 dp[x][0]=0;
25 dp[x][1]=1;
26 vis[x]=1;
27 for(int i=0;i<v[x].size();i++)
28 {
29 int to=v[x][i];
30 if(vis[to])
31 continue;
32 dfs(to);
33 //选根节点
34 dp[x][1]+=dp[to][0];
35 if(f[to][0])
36 {
37 f[x][1]=1;
38 }
39 //不选根节点
40 if(dp[to][0]>dp[to][1])
41 {
42 dp[x][0]+=dp[to][0];
43 if(f[to][0])
44 {
45 f[x][0]=1;
46 }
47 }
48 else
49 {
50 dp[x][0]+=dp[to][1];
51 if(f[to][1]||dp[to][0]==dp[to][1])
52 {
53 f[x][0]=1;
54 }
55 }
56 }
57 return ;
58 }
59 int main()
60 {
61 while(~scanf("%d",&n)&&n)
62 {
63 memset(vis,0,sizeof(vis));
64 memset(dp,0,sizeof(dp));
65 memset(f,0,sizeof(f));
66 for(int i=0;i<500;i++)
67 v[i].clear();
68 mp.clear();
69 cin>>s1;
70 int cnt=1;
71 if(!mp[s1])
72 {
73 mp[s1]=cnt++;
74 }
75 n--;
76 while(n--)
77 {
78 cin>>s1>>s2;
79 if(!mp[s1])
80 {
81 mp[s1]=cnt++;
82 }
83 if(!mp[s2])
84 {
85 mp[s2]=cnt++;
86 }
87 v[mp[s2]].push_back(mp[s1]);
88 }
89 flag=0;
90 dfs(1);
91 printf("%d ",max(dp[1][0],dp[1][1]));
92 if(dp[1][0]==dp[1][1])
93 {
94 puts("No");
95 }
96 else
97 {
98 if(dp[1][0]>dp[1][1])
99 {
100 if(f[1][0])
101 cout<<"No"<<endl;
102 else
103 cout<<"Yes"<<endl;
104 }
105 else if(dp[1][1]>dp[1][0])
106 {
107 if(f[1][1])
108 cout<<"No"<<endl;
109 else
110 cout<<"Yes"<<endl;
111 }
112
113 }
114 }
115 }