zoukankan      html  css  js  c++  java
  • LOJ 10160

    题面

    传送门

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

    你的任务是设计一份参加聚会者的名单,使总欢乐度最高。

    第一行是一个整数 $N$ 

    接下来 $N$ 行对应 $N$ 个职员的欢乐度,第 ii 行的一个整数为第 $i$ 个职员的欢乐度 $p_i$

    接着是学校的人事关系树,每一行格式为 L K ,表示第 $K$ 个职员是第 $L$ 个职员的直接上司,输入以 0 0 结束。

    输出参加聚会者获得的最大欢乐度。

    解题思路

    树形 DP ,设 $f[i][0]$ 表示第 i 个人不参加时他下面的所有人的最大欢乐值, $f[i][1]$ 表示第 i 个人参加时他下面的所有人的最大欢乐值(包括他)。

    然后我们找出树根,进行 dfs, $f[i][0]=sum_{j}^{jin i.son} max(f[j][0],f[j][1]),f[i][1]=sum_{j}^{jin i.son} f[j][0]$ 。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int n;
    struct node{//存储树的结点
    	int x,isroot;
    	vector<int> son;
    };
    node s[1000001];
    int f[1000001][2];
    void dfs(int x){
    	f[x][0]=0;
    	f[x][1]=s[x].x;//如果要选这个人,那么他的快乐值要加上
    	for (int i=0;i<s[x].son.size();i++){
    		dfs(s[x].son[i]);
    		f[x][0]+=max(f[s[x].son[i]][0],f[s[x].son[i]][1]);//状态转移
    		f[x][1]+=f[s[x].son[i]][0];
    	}
    }
    int main(){
    	cin>>n;
    	for (int i=1;i<=n;i++){
    		cin>>s[i].x;
    		s[i].isroot=1;
    	}
    	for (int i=1;i<=n-1;i++){
    		int x,y;
    		cin>>x>>y;
    		s[y].son.push_back(x);
    		s[x].isroot=0;//如果一个节点有父亲,那么它就不是根节点
    	}
    	for (int i=1;i<=n;i++){
    		if (s[i].isroot){
    			dfs(i);
    			cout<<max(f[i][0],f[i][1]);
    			return 0;
    		}
    	}
    }
  • 相关阅读:
    【Selenium IDE】下载安装Chrome和Firefox插件IDE ide了解就行 不是重点 重点是写脚本
    调用接口时,生产环境,路径加斜杠“/”和不加的区别
    WPF 踩坑笔记12 DataGrid触发选中行事件
    WPF 踩坑笔记11 线程取消
    WPF 踩坑笔记10 ListBox异步动态加载
    WPF 踩坑笔记9 直接打印
    思维的体操
    【洛谷 P4213】 【模板】杜教筛(Sum)
    【洛谷 P2257】 YY的GCD(莫比乌斯反演)
    【洛谷 P4980】 【模板】Pólya 定理
  • 原文地址:https://www.cnblogs.com/abc2237512422/p/10344555.html
Copyright © 2011-2022 走看看