zoukankan      html  css  js  c++  java
  • POJ 3342 (树形DP)

    题意 :给出一些上下级关系,要求i和i的直接上级不能同时出现,现在选出一些人构成一个集合,问你这个集合里面的最大人数是都少,同时给出这个最大的人数的集合是否唯一。

    思路:树形DP,dp[i][0],表示以i为跟节点的子树,不取i时的最优解,dp[i][1]表示以i为跟节点的子树,取i时的最优解,再另设only数组,only[i][0]表示以i为跟节点的子树,不i时最  优解是否唯一,only[i][1]表示以i为跟节点取i时最优解是否唯一

    #include<map>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 222
    using namespace std;
    typedef struct{
        int to, next;
    }Edge;
    Edge edge[MAXN];
    int dp[MAXN][2], head[MAXN];
    int only[MAXN][2], cnt;
    void addEdge(int u, int v, int k){
        edge[k].to = v;
        edge[k].next = head[u];
        head[u] = k;
    }
    void dfs(int s){
        dp[s][0] = 0;
        dp[s][1] = 1;
        for(int i = head[s];~i;i = edge[i].next){
            int u = edge[i].to;
            dfs(u);
            if(dp[u][0] > dp[u][1]){
                dp[s][0] += dp[u][0];
                if(only[u][0]) only[s][0] = 1;
            }else if(dp[u][0] < dp[u][1]){
                dp[s][0] += dp[u][1];
                if(only[u][1]) only[s][0] = 1;
            }else{
                dp[s][0] += dp[u][0];
                only[s][0] = 1;
            }
            dp[s][1] += dp[u][0];
            if(only[u][0]) only[s][1] = 1;
        }
    }
    int main(){
        int n, k;
        string s1, s2;
        map<string, int>mp;
       // freopen("in.c", "r", stdin);
        while(~scanf("%d", &n) && n){
            mp.clear(), k = 1, cnt = 0;
            cin >> s1;
            mp[s1] = k++;
            memset(head, -1, sizeof(head));
            memset(only, 0, sizeof(only));
            for(int i = 1;i <= n-1; i++){
                cin >> s1 >> s2;
                if(mp.find(s1) == mp.end()) mp[s1] = k++;
                if(mp.find(s2) == mp.end()) mp[s2] = k++;
                addEdge(mp[s2], mp[s1], i);
            }
            addEdge(0, 1, n);
            dfs(0);
            printf("%d ", max(dp[1][0], dp[1][1]));
            if(!only[0][0]) printf("Yes
    ");
            else printf("No
    ");        
        }
        return 0;
    }




  • 相关阅读:
    调试技术 Orisun 博客园
    Core Dump和/proc调试 Orisun 博客园
    再谈select, iocp, epoll,kqueue及各种I/O复用机制 Shallway 博客频道 CSDN.NET
    基础很重要
    Speech and Language Processing (2nd Ed.): Updates
    CS 288: Statistical Natural Language Processing
    对C++中string类型的总结
    HTTP代理实现请求报文的拦截与篡改1 jivi 博客园
    学习优秀源码 Orisun 博客园
    分享:苹果老员工可享两年离岗留职待遇
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3933151.html
Copyright © 2011-2022 走看看