Party at Hali-Bula(树形DP+判断方案数是否唯一)

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 }

原文地址:https://www.cnblogs.com/1013star/p/9942412.html

时间: 2024-10-10 15:01:15

Party at Hali-Bula(树形DP+判断方案数是否唯一)的相关文章

洛谷P1108 低价购买[DP | LIS方案数]

题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它.买的次数越多越好!你的目标是在遵循以上建议的前提下,求你最多能购买股票的次数.你将被给出一段时间内一支股票每天的出售价(2^16范围内的正整数),你可以选择在哪些天购买这支股票.每次购买都必须遵循“低价购买:再低价购买”的原则.写一个程序计算最大购买次数. 这里是某支股票的价格清单: 日期 1 2

HDU 1619 &amp; UVA 116 Unidirectional TSP(树形dp,入门 , 数塔变形)

Unidirectional TSP Description Background Problems that require minimum paths through some domain appear in many different areas of computer science. For example, one of the constraints in VLSI routing problems is minimizing wire length. The Travelin

[bzoj4472][树形DP] Salesman

题目 原地址 解说 刚看完这道题感觉还是挺乱的,可能那时候脑子不太清醒,一度觉得自己又要重拾Tarjan了.当然最后还是发觉应该用树形DP. (以下dp[u]代表以u为根的包括自己在内的子树的最大利润,bool g[u]表示u及其子树的方案数是否唯一,唯一则为0,否则为1,t[u]代表u的次数,v[u]代表u的价值) 计算最大利润确实挺简单.有点像之前做过的空调教室,但是多了次数限制和负数,但这不难处理.计算u的时候因为每个儿子在走完之后必须返回u来回到根节点,因此我们只能对儿子的dp值进行排序

[vijos1880]选课&lt;树形dp&gt;

题目链接:https://www.vijos.org/p/1180 这是一道树形dp的裸题,唯一的有意思的地方就是用到了多叉树转二叉树 然后本蒟蒻写这一道水题就是因为以前知道这个知识点但是没有怎么去实现,所以就写了这一道题来练一练手 将这道题的多叉树转换成二叉树后,接着就是状态转移方程了 我们先定义数组dp[i][j]表示第i门课,还可以选j门 然后我们可以想到,第i门课我们可以不选,如果不选,就不能去找i的左儿子,但是可以找i的右儿子,即i的右儿子(兄弟)选了j门 加入选了i,那么状态来源就是

vijos 1313 金明的预算方案 树形DP

描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今天一早,金明就开始做预算了,他把想买的物品分为两类:主件与附件,附件是从属于某个主件的,下表就是一些主件与附件的例子:主件 附件电脑 打印机,扫描仪书柜 图书书桌 台灯,文具工作椅 无如果要买归类为附件的物品,必须先买该附件所属的主件.每个主件可以有0个.1个或2个附件.附件不再有从属于自己的附件.金明

青云的机房组网方案(简单+普通+困难)(虚树+树形DP+容斥)

题目链接 1.对于简单的版本n<=500, ai<=50 直接暴力枚举两个点x,y,dfs求x与y的距离. 2.对于普通难度n<=10000,ai<=500 普通难度解法挺多 第一种,树形dp+LCA 比赛的时候,我猜测对于不为1的n个数,其中两两互质的对数不会很多,肯定达不到n^2 然后找出所有互质的对数,然后对为1的数进行特殊处理.(初略的估计了下,小于500的大概有50个质数,将n个数平均分到这些数中,最后大概有10000*50*200=10^7) 对所有的非1质数对,采用离

Codeforces 461B. Appleman and Tree[树形DP 方案数]

B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other vertices are color

树形dp

树形dp,意思就是在树上的dp, 看了看紫书,讲了三个大点把,一个是树的最大独立集,另外一个是树的重心,最后一个是树的最长路径.给的三个例题,下面就从例题说起 第一个:工人的请愿书 uva 12186 这个题目给定一个公司的树状结构,每个员工都有唯一的一个直属上司,老板编号为0,员工1-n,只有下一级的工人请愿书不小于T%时,这个中级员工,才会签字传递给它的直属上司,问老板收到请愿书至少需要多少各个工人签字 用dp(u)表示u给上级发信至少需要多少工人,那么可以假设u有k个节点,所以需要c =

[vijos1892]树上的最大匹配(树形DP)

题目:https://vijos.org/p/1892 分析:(100分其实用到各种c++优化,没什么实际意义,所以弄70就可以了) 题目很简单,很容易想出用树形DP,但是求方案数的时候,满满都是细节……,本渣考试时候就跪了……只能膜拜神犇代码…… 1 #include <cstdio> 2 #include <cstring> 3 //#include <algorithm> 4 5 using namespace std; 6 7 typedef long long