hdu2412(树形dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2412
题意:给定一棵关系树 , 从中选择一些点 , 使这些点均不存在亲子关系 , 最多能取多少个点 , 并且判断取法是否唯一 .
分析:如果这题没有判断唯一性,就和hdu1520一样了。设 dp[i][0] 为在以 i 为根的子树中 , 不选择点 i 最多能够选的数目 ,dp[i][1] 为选择 i 点的最多数目 .
状态转移方程 :
当 u 为叶子节点时 :
dp[u][0]=0;
dp[u][1]=1;
当 u 为非叶子节点时 :
dp[u][0]=sum(max(dp[v][0],dp[v][1])) (v 为 u 的儿子 )
dp[u][1]=sum(dp[v][0]) (v 为u 的儿子 )
至于判断唯一性:初始化flag数组全为1,即可行的唯一的。如果父节点以下的某一节点取时不唯一了,递归上去的结果也必定不唯一。
if(dp[v][0]>dp[v][1]&&flag[v][0]==0)flag[u][0]=0;//如果取子节点v即dp[v][0]时而flag[v][0]=0;由于dp[u][0]会取dp[v][0]使得flag[u][0]也变为0,即不唯一了
else if(dp[v][1]>dp[v][0]&&flag[v][1]==0)flag[u][0]=0;;//同理取dp[v][1]时而flag[v][1]=0;由于dp[u][0]会取dp[v][1]使得flag[u][0]也变为0,即不唯一了
else if(dp[v][0]==dp[v][1])flag[u][0]=0;//不唯一的源头
if(flag[v][0]==0)flag[u][1]=0;//由于dp[u][1]必取dp[v][0],所以flag[v][0]为0的话,flag[u][1]也不唯一了。
#pragma comment(linker,"/STACK:102400000,102400000")
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>
#include <stack>
#include <vector>
#include <set>
#include <map>
#define LL long long
#define mod 1000000007
#define inf 0x3f3f3f3f
#define N 210
#define FILL(a,b) (memset(a,b,sizeof(a)))
using namespace std;
struct edge
{
int next,v;
edge(){}
edge(int v,int next):v(v),next(next){}
}e[N*];
int head[N],tot;
int num,n;
int dp[N][],flag[N][];
void addedge(int u,int v)
{
e[tot]=edge(v,head[u]);
head[u]=tot++;
}
void dfs(int u,int fa)
{
dp[u][]=;dp[u][]=;
flag[u][]=flag[u][]=;
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].v;
if(v==fa)continue;
dfs(v,u);
dp[u][]+=dp[v][];
dp[u][]+=max(dp[v][],dp[v][]);
if(dp[v][]>dp[v][]&&flag[v][]==)flag[u][]=;
else if(dp[v][]>dp[v][]&&flag[v][]==)flag[u][]=;
else if(dp[v][]==dp[v][])flag[u][]=;
if(flag[v][]==)flag[u][]=;
}
} char str[N],s1[N],s2[N];
int main()
{
while(scanf("%d",&n)&&n)
{
tot=;num=;
map<string,int>mp;
FILL(head,-);
scanf("%s",str);
mp[str]=++num;
for(int i=;i<n;i++)
{
scanf("%s%s",s1,s2);
if(mp.find(s1)==mp.end())mp[s1]=++num;
if(mp.find(s2)==mp.end())mp[s2]=++num;
addedge(mp[s1],mp[s2]);
addedge(mp[s2],mp[s1]);
}
dfs(,-);
if(dp[][]>dp[][]&&flag[][]==)
printf("%d Yes\n",dp[][]);
else if(dp[][]>dp[][]&&flag[][]==)
printf("%d Yes\n",dp[][]);
else printf("%d No\n",max(dp[][],dp[][]));
}
}
hdu2412(树形dp)的更多相关文章
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
- BZOJ 1040 树形DP+环套树
就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...
随机推荐
- perl 改变对象属性
[root@wx03 test]# cat Critter.pm package Critter; #unshift(@INC,"/root/test"); #use messag ...
- hdu 1760 一道搜索博弈题 挺新颖的题目
A New Tetris Game Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- Linux下使用Mysql
一.连接MySQL数据库 一个最简单的程序示例: #include <stdio.h> #include "mysql.h" int main() { MYSQL my ...
- 关于Smartforms换页的
smartforms中有系统变量SFSY-PAGE是总页码,SFSY-FORMPAGES是当前页,可以最后的窗体中做个判断 1.把窗体设置成最终窗体 2.新增一个命令,当前页等于最后一页才输出改内容, ...
- uva 147 Dollars(完全背包)
题目连接:147 - Dollars 题目大意:有11种硬币, 现在输入一个金额, 输出有多少种组成方案. 解题思路:uva 674 的升级版,思路完全一样, 只要处理一下数值就可以了. #inclu ...
- 如何将excel文件中的数百万条数据在1分钟内导入数据库?
在MYSQL里面,使用load data infile 命令就可以了. 步骤很简单 1.先将excel另存为csv格式的文本,csv是以逗号分隔各个字段数据的 2.在mysql中输入sql语句 loa ...
- 怎样取消shutdown关机命令?-shutdown命令的使用解析
机房上课,可恶电脑总是被管理员測试,不时地弹出这个关机提示.怎样取消这个关机命令呢?其有用 shutdown -a 就可以.以下来学习一下shutdown命令的使用: shutdown这个命令预计 ...
- Swift代码实现加载WEBVIEW
let webview = UIWebView(frame:self.view.bounds) webview.bounds=self.view.bounds //远程网页 webview.loadR ...
- 关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)
关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short ...
- 如何隐藏 QLPreviewController 的 Action 按钮?
在 iOS 6 以前,可以在 present QLPreviewController 之后使用以下代码: [previewController.navigationItem setRightBarBu ...