zoukankan      html  css  js  c++  java
  • 周年纪念晚会

    试题描述

    Ural 州立大学的校长正在筹备学校的 80 周年纪念聚会。由于学校的职员有不同的职务级别,可以构成一棵以校长为根的人事关系树。每个资源都有一个唯一的整数编号,从 1 到 N 编号,且对应一个参加聚会所获得的欢乐度。为使每个职员都感到快乐,校长设法使每个职员和其直接上司不会同时参加聚会。你的任务是设计一份参加聚会者的名单,使总欢乐度最高。

    输入
    第一行是一个整数 N;接下来 N 行对应 N 个职员的欢乐度,第 i 行的一个整数为第 i 个职员的欢乐度 pi​ ;接着是学校的人事关系树,每一行格式为 L K ,表示第 K 个职员是第 L 个职员的直接上司,输入以 0 0 结束。
    输出
    输出参加聚会者获得的最大欢乐度。
    输入示例
    7
    1
    1
    1
    1
    1
    1
    1
    1 3
    2 3
    6 4
    7 4
    4 5
    3 5
    0 0
    输出示例
    5
    其他说明
    数据范围:对于 100% 的数据,1 <= N <= 6000,−128 <= pi <= 127 。

     看注释

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    using namespace std;
    inline int rd()
    {
        int x=0,f=1;
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';
        return x*f;
    }
    inline void write(int x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
        return ;
    }
    int n;
    int head[100006],to[100006],nxt[100006];
    int total=0;
    int dis[100006];
    void add(int x,int y)
    {
        total++;
        to[total]=y;
        nxt[total]=head[x];
        head[x]=total;
        return ;
    }
    int f[100006][3];
    void dfs(int x,int la)
    {
        /*
            状态一共只有两种,分别是去 f[x][1]   或不去   f[x][0]
        */ 
        f[x][1]=dis[x];
        for(int e=head[x];e;e=nxt[e])
        {
            int h=to[e];
            if(h!=la)
            {
                dfs(h,x);
                /*
                    一定是+=   因为子树有很多,而且结果是累加的 
                */ 
                f[x][0]+=max(f[h][0],f[h][1]);//因为没有规定上司不去下属就一定去,所以要在两个值里取最大的 
                f[x][1]+=f[h][0];
            }
        }
        return ;
    }
    int book[100006];
    int main()
    {
        /*
            上来第一眼,树形DP裸题 
        */ 
        memset(book,0,sizeof(book));
        n=rd();
        for(int i=1;i<=n;i++) dis[i]=rd();
        while(1)
        {
            int x,y;
            x=rd();
            y=rd();
            if(x==0&&y==0) break;
            add(y,x);//单向存边,因为上次不会因为下属去就不开心 
            book[x]=1;
        }
        int root=1;//选择一个没有上司的作为根节点,但看别人没写也过了 ??? 
        while(book[root]) root++;
        dfs(root,0);
        printf("%d",max(f[root][0],f[root][1]));//在上司去和不去中取最大值   坑啊!! 
        return 0;
    }

    最后喜欢的话不如来推荐,评论,关注三连。

    不喜欢的话也昧着良心推荐一下吧!!!!

    蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿
  • 相关阅读:
    一.django初识
    解决Centos7下中文显示乱码
    宿主机ping不通虚拟机,虚拟机能ping通宿主机问题
    Win7查看某个端口被占用的解决方法
    改变securecrt背景色
    一.1搭建跨平台的统一python开发环境
    第二部分用户交互程序开发,通过paramiko记录ssh会话记录
    【VUE+Django】天坑》》 模板语法与VUE语法的冲突
    【vue_django】成功登录后,保存用户
    【Vue+django】 配合rest_framework的惊天大坑
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9505068.html
Copyright © 2011-2022 走看看