Party at Hali-Bula(樹形DP+判斷方案數是否唯一)
阿新 • • 發佈:2018-11-11
blank ret algo 以及 scan enter clear return nbsp
Party at Hali-Bula
UVA - 1220
題意:
公司裏有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 }
Party at Hali-Bula(樹形DP+判斷方案數是否唯一)