UVA-01220 Party at Hali-Bula (树形DP+map)

题目链接:https://vjudge.net/problem/UVA-1220



思路:

  • 树形DP模板题,求最大人数很简单,难点在于如何判断最大人数的名单是否有不同的情况;
  • 解决方法是用一个数组f[manx][2]记录该节点是否出场的情况,为真时代表有多种情况;
  • 具体讨论:
  1. 当父节点的值加上某个子节点的值时,他的f的情况也和该子节点一样;
  2. 当某个节点dp(i, 0) == dp(i, 1), 则该节点以及它的父节点也一定有多种情况(父节点必定取其中之一)。

Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 map<string, int> mp;
 4 vector<int> T[210];
 5 int dp[210][2];
 6 bool f[210][2];
 7 
 8 void dfs(int x, int fa) {
 9     int len = T[x].size();
10     for (int i = 0; i < len; ++i)
11         dfs(T[x][i], x);
12     dp[fa][1] += dp[x][0];
13     if (f[x][0]) f[fa][1] = 1;
14     if (dp[x][1] > dp[x][0]) {
15         dp[fa][0] += dp[x][1];
16         if (f[x][1]) f[fa][0] = 1;
17     }
18     else {
19         dp[fa][0] += dp[x][0];
20         if (f[x][0] || dp[x][1] == dp[x][0]) f[fa][0] = 1;
21     }
22 }
23 
24 int main() {
25     int n, tot;
26     string boss, fa, son;
27     while(cin>>n, n) {
28         memset(dp, 0, sizeof(dp));
29         memset(f, 0, sizeof(f));
30         mp.clear();
31         cin>>boss;
32         mp[boss] = tot = 1;
33         int ff, s;
34         for (int i = 1; i < n; ++i) {
35             cin>>son>>fa;
36             if (mp.count(fa)) ff = mp[fa];
37             else ff = ++tot, mp[fa] = ff;
38             if (mp.count(son)) s = mp[son];
39             else s = ++tot, mp[son] = s;
40             T[ff].push_back(s);
41             dp[i][1] = 1;
42         }
43         dp[n][1] = 1;
44         dfs(1, 0);
45         bool flag = 1;
46         int ans = max(dp[1][0], dp[1][1]);
47         if (dp[1][1] == dp[1][0]) flag = 0;
48         else if (dp[1][1] > dp[1][0]) {if (f[1][1]) flag = 0;}
49         else if (dp[1][1] < dp[1][0]) {if (f[1][0]) flag = 0;}
50         cout<<ans<<" ";
51         if (flag) cout<<"Yes"<<endl;
52         else cout<<"No"<<endl;
53         for (int i = 0; i <= n; ++i) T[i].clear();
54     }
55 
56     return 0;
57 }

 

posted @ 2017-02-06 22:58  Robin!  阅读(205)  评论(0编辑  收藏  举报