ACM PKU 3342 Party at Hali-Bula http://poj.org/problem?id=3342

好久没有认真写过解题报告了,今天白天做题做纠结了,晚上趁着这个纠结的时间好好写一个题的解题报告吧,希望我的报告后来者能看懂;

ACM PKU 3342 Party at Hali-Bula http://poj.org/problem?id=3342 这道题;

题目大意是:一个聚会要邀请最多的人参加,但是又担心老板和员工在一起会玩得不高兴,所以老板去了那么他得直属员工就不能去,题目最终目的是找一个解决方案找到一个最优解(即最多人数)同时回答这个问题是不是唯一解。

对于求解问题dp[i][2]=0标示当前节点不参加聚会,dp[i][2]=1表示当前节点参加聚会;有如下状态转移方程:

  1. dp[u][0]+=max{dp[v][0],dp[v][1]}  //表示的意思是,如果当前节点不参加聚会,则我会在当前节点的儿子节点(即员工)参加聚会和不参加聚会中选择一个最大值;
  2. dp[u][1]+=dp[v][0];           //表示的意思是,如果当前节点参加聚会,则它的下属一定不能参加聚会,可以直接通过员工节点获得最大值;

对于求解问题解是否唯一时,通过d[i][2]来标示,d[i][2]=0标示解不唯一,d[i][2]=1标示解唯一,这里要分情况讨论;

  1. 对于状态转移方程一有:如果老板不参加聚会,那么员工可以参加也可以不参加聚会,这里又有三种情况需要讨论:
  • 如果当员工参加聚会时不去的人数更多,那么解是不是唯一由员工去的解是不是唯一决定,如果员工不去的解不唯一,那么,d[u][0]=0;
  • 如果当员工参加聚会时去的人数更多,那么解是不是唯一由员工去的解是不是唯一决定,如果员工去的解不唯一,那么,d[u][1]=0;
  • 如果员工去不去的人数相等,很明显的两种情况,那么必有d[u][0]=0;

  2.对于状态转移方程二有:如果老板参加聚会,那么解是不是唯一必定由员工不去决定,此时有:

  • 如果员工不去的不唯一,那么老板去的解必定会不唯一,那么必有:d[u][1]=0;

说了这么多不知道有没有说清楚,下面附上我的AC代码,有不懂得欢迎留言探讨;

 1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <map>
6
7 using namespace std;
8
9 const int maxn=201;
10
11 struct node {
12 int to,next;
13 }edge[maxn*10];
14
15 int ecnt,box[maxn];
16
17 int d[maxn][2],dp[maxn][2];
18
19 void _make_map(int from,int to)
20 {
21 edge[ecnt].to=to;
22 edge[ecnt].next=box[from];
23 box[from]=ecnt++;
24 }
25
26 void make_map(int from,int to)
27 {
28 _make_map(from,to);
29 _make_map(to,from);
30 }
31
32 void dfs(int u,int p)
33 {
34 //cout<<p<<" "<<u<<endl;
35 dp[u][0]=0;
36 dp[u][1]=1;
37 for(int i=box[u];i+1;i=edge[i].next)
38 {
39 int v=edge[i].to;
40 if(v==p)continue;
41 dfs(v,u);
42 if(dp[v][0]>dp[v][1]&&!d[v][0]) d[u][0]=0;
43 if(dp[v][1]>dp[v][0]&&!d[v][1]) d[u][0]=0;
44 if(dp[v][0]==dp[v][1]) d[u][0]=0;
45 if(!d[v][0]) d[u][1]=0;
46 dp[u][0]+=max(dp[v][0],dp[v][1]);
47 dp[u][1]+=dp[v][0];
48 }
49 }
50
51 int main()
52 {
53 int n_case;
54 while (scanf("%d",&n_case) &&n_case!=0)
55 {
56 map<string,int> mymap;
57 memset(box,-1,sizeof(box));
58 memset(d,1,sizeof(d));
59 int cnt=1;
60 ecnt=0;
61 string bigboss;
62 cin>>bigboss;
63 mymap[bigboss]=cnt++;
64 for(int i=1;i<n_case;i++)
65 {
66 string employee,boss;
67 cin>>employee>>boss;
68 if(!mymap[employee]) mymap[employee]=cnt++;
69 if(!mymap[boss]) mymap[boss]=cnt++;
70 make_map(mymap[employee],mymap[boss]);
71 }
72 dfs(1,1);
73 int temp=dp[1][0]>dp[1][1]?dp[1][0]:dp[1][1];
74 printf("%d ",temp);
75 if(dp[1][0]>dp[1][1])
76 {
77 if(d[1][0]) printf("Yes\n");
78 else printf("No\n");
79 }
80 else if(dp[1][1]>dp[1][0])
81 {
82 if(d[1][1]) printf("Yes\n");
83 else printf("No\n");
84 }
85 else printf("No\n");
86 }
87 return 0;
88 }

  

posted on 2011-08-07 18:57  _Clarence  阅读(220)  评论(0编辑  收藏  举报

导航