zoukankan      html  css  js  c++  java
  • hdu 2412 Party at HaliBula (树形DP)

    题意跟hdu1520一样,给定一棵树,要求选出若干个点,但如果选择了父节点跟儿子节点不可以同时选。。求可以选出的节点数的最大值,同时,判断该选法是否唯一;

    分析:前半部分很容易实现,普通的树形dp,关键是如何判断是否唯一。

    我们用flag[N][2]来记录每一个节点的情况

    flag[i][j]为真,表示唯一

    则可以这样判断

    对于叶子结点, flag[k][0] = flag[k][1] = 1.
    对于非叶子结点,
    对于i的任一儿子j,若(dp[j][0] > dp[j][1] 且 flag[j][0] == 0) 或 (dp[j][0] < dp[j][1] 且 flag[j][1] == 0) 或 (dp[j][0] == dp[j][1]),则flag[i][0] = 0
    对于i的任一儿子j有flag[j][0] = 0, 则flag[i][1] = 0
    View Code
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<vector>
    using namespace std;
    const int N =210;
    int n,num,dp[N][2];
    vector<int> g[N];
    bool flag[N][2];
    typedef struct node
    {
    int cnt;
    struct node *next[52];
    }*tree,Trie;
    tree root;
    inline int GetNum(char *t){
    tree p = root,newnode;
    for(int i = 0;i < strlen(t); ++i){
    int u = t[i] - 'a';
    if(u<0) u=t[i]-'A'+26;
    if(p->next[u]==NULL)
    {
    newnode=(tree)malloc(sizeof(Trie));
    newnode->cnt=-1;
    for(int j=0;j<52;j++)
    newnode->next[j]=NULL;
    p->next[u]=newnode;
    p=newnode;
    }
    else
    p = p->next[u];
    }
    if(p->cnt == -1) //该节点未出现过
    p->cnt = num ++;
    return p->cnt;
    }
    void init()
    {
    root=(tree)malloc(sizeof(Trie));
    root->cnt=-1;
    for(int j=0;j<52;j++)
    root->next[j]=NULL;
    num=1;
    for(int i=0;i<=n;i++)
    g[i].clear();
    memset(dp,0,sizeof(dp));
    memset(flag,true,sizeof(flag));
    }
    void dfs(int u)
    {
    int size=g[u].size();
    for(int i=0;i<size;i++)
    {
    int v=g[u][i];
    dfs(v);
    dp[u][1]+=dp[v][0];
    dp[u][0]+=max(dp[v][0],dp[v][1]);;
    if(( dp[v][0]>dp[v][1] && !flag[v][0])|| (dp[v][0]<dp[v][1] && !flag[v][1]) || dp[v][0]==dp[v][1])
    flag[u][0]=false;
    if(!flag[v][0])
    flag[u][1]=false;
    }
    dp[u][1]++;
    }

    int main()
    {
    char str[200],str1[200];
    int a,b;
    while(scanf("%d",&n)==1 && n)
    {
    init();
    scanf("%s",str);
    int s=GetNum(str);
    for(int i=1;i<n;i++)
    {
    scanf("%s %s",str,str1);
    a=GetNum(str);
    b=GetNum(str1);
    g[b].push_back(a);
    }
    dfs(s);
    printf("%d ",max(dp[s][0],dp[s][1]));
    if(dp[s][0]>dp[s][1] && flag[s][0])
    puts("Yes");
    else if(dp[s][1]>dp[s][0] && flag[s][1])
    puts("Yes");
    else puts("No");
    }
    return 0;
    }
  • 相关阅读:
    SDK Tools Dependencies
    hibernate开发中遇到多对多的问题,可以转换为两个一对多
    利用PC 转发 模拟手机端之间socket通信
    假如你被当成精神病关进了精神病院
    通过JSONP实现完美跨域
    查看linux系统版本命令
    Eclipse+python开发环境配置
    linux chkconfig命令参数及用法详解
    Fedora 17 安装后要做的几件事:MP3,桌面定制,root登录等
    Fedora 17 配置 Nginx + Mysql + php
  • 原文地址:https://www.cnblogs.com/nanke/p/2384421.html
Copyright © 2011-2022 走看看