HDU 2412 Party at Hali-Bula

树形DP水题。判断取法是否唯一,dp的时候记录一下每个状态从下面的子节点推导过来的时候是否唯一即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<map>
#include<vector>
#include<string>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn=200+10;
map<string,int>v;
vector<int>tree[maxn];
int n,id;
int dp[maxn][5],flag[maxn][5];
string s;
bool vis[maxn];

void init()
{
    id=0;
    v.clear();
    memset(dp,0,sizeof dp);
    memset(flag,0,sizeof flag);
    memset(vis,0,sizeof vis);
    for(int i=0;i<=n;i++) tree[i].clear();
}

void read()
{
    cin>>s;
    if(!v[s]) v[s]=++id;
    for(int i=1;i<=n-1;i++)
    {
        int a,b;
        cin>>s; if(v[s]==0) v[s]=++id;
        a=v[s];
        cin>>s; if(v[s]==0) v[s]=++id;
        b=v[s];
        tree[a].push_back(b);
        tree[b].push_back(a);
    }
}

void dfs(int now)
{
    bool fail=1;
    for(int i=0;i<tree[now].size();i++)
        if(!vis[tree[now][i]]) fail=0;

    if(fail)
    {
        dp[now][1]=1;
        dp[now][0]=0;
        return;
    }

    int sum1=1,sum2=0;

    for(int i=0;i<tree[now].size();i++)
    {
        int id=tree[now][i];
        if(vis[id]) continue;

        vis[id]=1; dfs(id);

        sum1=sum1+dp[id][0];
        if(flag[id][0]==1) flag[now][1]=1;

        sum2=sum2+max(dp[id][1],dp[id][0]);
        if(dp[id][1]==dp[id][0]) flag[now][0]=1;
        else if(dp[id][1]>dp[id][0]){if(flag[id][1]) flag[now][0]=1;}
        else {if(flag[id][0]) flag[now][0]=1;}
    }
    dp[now][1]=sum1;
    dp[now][0]=sum2;

}

void work()
{
    vis[1]=1;
    dfs(1);
    printf("%d ",max(dp[1][0],dp[1][1]));
    bool ans=0;
    if(dp[1][0]>dp[1][1]) {if(flag[1][0]) ans=1;}
    else if(dp[1][0]<dp[1][1]) {if(flag[1][1]) ans=1;}
    else ans=1;
    if(ans) printf("No\n");
    else printf("Yes\n");
}

int main()
{
    while(~scanf("%d",&n))
    {
        if(!n) break;
        init();
        read();
        work();
    }
    return 0;
}
时间: 2024-11-14 23:27:22

HDU 2412 Party at Hali-Bula的相关文章

hdu - 2412 - Party at Hali-Bula(树形dp)

题意:一棵n个结点的有根树(1 <= n <= 200),问最多能找出多少个结点使得找出的结点中任意两个结点没有直接相连的父子关系,并判断这个最大值方案是否唯一. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2412 -->>状态: dp[i][1]表示以结点 i 为根的子树,且选择i,能找出的满足要求的最大结点数. dp[i][0]表示以结点 i 为根的子树,且不选择i,能找出的满足要求的最大结点数. 状态转移方程(结点 j 是结

【树形DP】 HDU 2412 Party at Hali-Bula

给出根节点(BOSS) 然后还有N-1个边  A B 由B指向A (B为A 的上司) 每次只能选择这个关系中的其中一个 求最多选几个点 并且输出是不是唯一的 重点判断是否唯一: 1.若下属不去和去都人数一样的话则上司不去的话就不唯一(上司去了下属必定不能去,所以不满足) 2.若下属不去还不唯一的话  上司去了也是不唯一 #include <cstdio> #include <cstdlib> #include <cstring> #include <climits

HDU 2412 Farm Irrigation

题目: Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is ma

hdu 2412 树形dp

1 /* 2 题目大意:一个n个节点的树,求选取一些节点(不能含有父子关系的)的最大数量,且是否唯一. 3 dp(i,0)表示当前节点i不选,dp(i,1)表示当前节点i选 4 叶子节点dp(i,0)=0,dp(i,1)=1 5 dp(i,0)=sigma(max(dp(j,0),dp(j,1))) (j是i的儿子) 6 dp(i,1)=sigma(dp(j,0))+1(j是i的儿子) 7 最多人数为max(dp(0,0),dp(0,1))(0表示根节点) 8 用flag数组标记结果是否唯一 9

HDU 2377 &amp;&amp; ZOJ 2412

~~~~ 输入好长... 思路就是对线路上的每一个点BFS记录各个点到其所需的star值,然后ans记录所需的最大star值,最后输出ans最小的star值及相应的id. 开始建链接矩阵,结果MLE,于是修改了下. 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2377 http://acm.zju.edu.cn/onlinejudge/showProblemStatus.do?problemId=1912 ~~~~ #include<iostr

(hdu step 1.3.5)Fighting for HDU(排序)

题目: Fighting for HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2412 Accepted Submission(s): 1210   Problem Description 在上一回,我们让你猜测海东集团用地的形状,你猜对了吗?不管结果如何,都没关系,下面我继续向大家讲解海东集团的发展情况:在最初的两年里,HDU发

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;

HDU 5542 The Battle of Chibi dp+树状数组

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5542 题意:给你n个数,求其中上升子序列长度为m的个数 可以考虑用dp[i][j]表示以a[i]结尾的长度为j的上升子序列有多少 裸的dp是o(n2m) 所以需要优化 我们可以发现dp的第3维是找比它小的数,那么就可以用树状数组来找 这样就可以降低复杂度 #include<iostream> #include<cstdio> #include<cstring> #include

hdu 1207 汉诺塔II (DP+递推)

汉诺塔II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4529    Accepted Submission(s): 2231 Problem Description 经典的汉诺塔问题经常作为一个递归的经典例题存在.可能有人并不知道汉诺塔问题的典故.汉诺塔来源于印度传说的一个故事,上帝创造世界时作了三根金刚石柱子,在一根柱子上从下往