• 树形dp poj 2342


    题目链接:poj 2342

    题目大意:某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上司,现在已知每个人的活跃指数和上司关系(当然不可能存在环),求邀请哪些人(多少人)来能使得晚会的总活跃指数最大。

    思路:既然是树形dp,自然先建立一颗树了,这里用的是邻接表(L<-K)。找根的时候利用flag数组来标记所有儿子节点,那么没有标记的自然是根节点了。树形dp从叶子节点开始dp,所以深搜到叶子节点,然后不断回溯给父节点。在处理儿子节点时,父节点不参加的话儿子节点,取去与不去中的最大值;父亲节点参加那么儿子节点就不能去了。这里定义dp[][2],0表示不去,1表示去。具体运用参看代码。。。。。。。。。。。。。

    /**************************************************************
        Problem:poj 2342
        User: youmi
        Language: C++
        Result: Accepted
        Time:16MS
        Memory:408K
    ****************************************************************/
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#include<bits/stdc++.h>
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <stack>
    #include <sstream>
    #include <cmath>
    #include <queue>
    #include <string>
    #include <vector>
    #define zeros(a) memset(a,0,sizeof(a))
    #define ones(a) memset(a,-1,sizeof(a))
    #define sc(a) scanf("%d",&a)
    #define sc2(a,b) scanf("%d%d",&a,&b)
    #define rep0(i,n) for(int i=0;i<n;i++)
    #define rep1(i,n) for(int i=1;i<=n;i++)
    #define Max(a,b) (a)>(b)?(a):(b)
    #define Min(a,b) (a)<(b)?(a):(b)
    #define pt(a) printf("%d
    ",a)
    #define lson (step<<1)
    #define rson (lson+1)
    #define esp 1e-6
    #define oo 0x3fffffff
    #define TEST cout<<"*************************"<<endl
    
    using namespace std;
    typedef long long ll;
    int n;
    const int maxn=6000+10;
    int dp[maxn][2];
    int vis[maxn];
    int head[maxn];
    int flag[maxn];
    int T;
    struct side
    {
        int v,next;
    }e[maxn];
    void init()
    {
        T=0;
        zeros(vis);
        zeros(dp);
        zeros(flag);
        ones(head);
    }
    void build(int u,int v)
    {
        e[T].v=v;
        e[T].next=head[u];
        head[u]=T++;
    }
    void tree_dp(int root)
    {
        vis[root]=1;
        //pt(root);
        for(int i=head[root];~i;i=e[i].next)
        {
            int v=e[i].v;
            if(!vis[v])
            {
                 tree_dp(v);
                 dp[root][1]+=dp[v][0];
                 dp[root][0]+=Max(dp[v][1],dp[v][0]);
            }
        }
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        /**<  int T_T;sc(T_T);
        for(int kase=1;kase<=T_T;kase++)*/
        //while(~sc(n))
        sc(n);
        {
            init();
            int root;
            rep1(i,n)
            {
                sc(dp[i][1]);
            }
            int u,v;
            rep1(i,n-1)
            {
                sc2(u,v);
                //printf("%d %d
    ",u,v);
                build(v,u);
                flag[u]=1;
            }
            rep1(i,n)
            {
                if(!flag[i])
                {
                    root=i;
                    break;
                }
            }
            //pt(root);
            tree_dp(root);
            pt(Max(dp[root][1],dp[root][0]));
        }
        return 0;
    }
    不为失败找借口,只为成功找方法
  • 相关阅读:
    【Redis】集群NetCore实战
    【Redis】集群教程(Windows)
    【Redis】入门
    【SQL SERVER】索引
    【SQL SERVER】锁机制
    【SQL SERVER】数据内部存储结构简单探索
    Windows软件包管理工具
    Git常用命令记录
    【ASP.NET Core学习】远程过程调用
    CouchDB学习-API
  • 原文地址:https://www.cnblogs.com/youmi/p/4633707.html
Copyright © 2020-2023  润新知