• 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;
    }




  • 相关阅读:
    Whidbey 开发
    构建软件数字安全带系列课程
    微软产品生命周期模型系列课程
    Windows Mobile 2nd 开发黄金周
    微软高性能运算系列课程
    _tmain()和main()区别
    简单工厂模式&工厂方法模式
    单例模式
    java中去除字符串(String)中的换行字符(\r \n \t)
    阿里巴巴 Java开发手册1.4.0
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3933151.html
Copyright © 2020-2023  润新知