P1352 没有上司的舞会

题目描述

某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入输出格式

输入格式:

第一行一个整数N。(1<=N<=6000)

接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)

接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。

最后一行输入0 0

输出格式:

输出最大的快乐指数。

输入输出样例

输入样例#1: 复制

7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
输出样例#1: 复制

5

树形DP——DFS版

#include<bits/stdc++.h>

#define N 6005
using namespace std; int n,r[N],dp[N][],tot,head[N];
struct node{
int to,next;
}e[N]; bool v[N];
void add(int u,int v){
e[++tot].to=v,e[tot].next=head[u],head[u]=tot;
}
//dp[i][0]表示i点不被选择时最大值
//dp[i][1]表示i点被选择时的最大值
void tredp(int u){
dp[u][]=,dp[u][]=r[u];
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
tredp(v);
dp[u][]+=max(dp[v][],dp[v][]);
dp[u][]+=dp[v][];
}
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&r[i]);
for(int a,b,i=;i<n;i++){
scanf("%d%d",&a,&b);
add(b,a);v[a]=;
}
int root;
for(int i=;i<=n;i++) if(!v[i]) root=i;
tredp(root);
printf("%d\n",max(dp[root][],dp[root][]));
return ;
}

树形DP——倒序队列或栈

#include<bits/stdc++.h>

#define N 6005
using namespace std; int n,r[N],dp[N][],tot,head[N];
struct node{
int to,next;
}e[N]; bool v[N];
void add(int u,int v){
e[++tot].to=v,e[tot].next=head[u],head[u]=tot;
}
//dp[i][0]表示i点不被选择时最大值
//dp[i][1]表示i点被选择时的最大值
queue<int>Q;
stack<int>q;
bool vis[N];
void bfs(int root){
Q.push(root);
while(!Q.empty()){
int u=Q.front();Q.pop();q.push(u);
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
if(!vis[v]){
vis[v]=;
Q.push(v);
}
}
}
while(!q.empty()){
int u=q.top();q.pop();
for(int i=head[u];i;i=e[i].next){
int v=e[i].to;
dp[u][]+=max(dp[v][],dp[v][]);
dp[u][]+=dp[v][];
}dp[u][]+=r[u];
}
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&r[i]);
for(int a,b,i=;i<n;i++){
scanf("%d%d",&a,&b);
add(b,a);v[a]=;
}
int root;
for(int i=;i<=n;i++) if(!v[i]) root=i;
bfs(root);
printf("%d\n",max(dp[root][],dp[root][]));
return ;
}

拓扑排序——反向建边

#include<bits/stdc++.h>

#define N 6005
using namespace std; int n,r[N],dp[N][],tot,head[N],rd[N];
struct node{
int to,next;
}e[N]; void add(int u,int v){
e[++tot].to=v,e[tot].next=head[u],head[u]=tot;
}
//dp[i][0]表示i点不被选择时最大值
//dp[i][1]表示i点被选择时的最大值
bool v[N];
queue<int>Q;
void topo(){
for(int i=;i<=n;i++) if(!rd[i]) Q.push(i);
while(!Q.empty()){
int u=Q.front();Q.pop();dp[u][]+=r[u];
for(int i=head[u];i;i=e[i].next){
int V=e[i].to;
rd[V]--;
if(!rd[V]) Q.push(V);
dp[V][]+=max(dp[u][],dp[u][]);
dp[V][]+=dp[u][];
}
}
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&r[i]);
for(int a,b,i=;i<n;i++){
scanf("%d%d",&a,&b);
add(a,b);rd[b]++;v[a]=;
}
int root;
for(int i=;i<=n;i++) if(!v[i]) root=i;
topo();
printf("%d\n",max(dp[root][],dp[root][]));
return ;
}

P1352 没有上司的舞会——树形DP入门的更多相关文章

  1. P1352 没有上司的舞会&&树形DP入门

    https://www.luogu.com.cn/problem/P1352 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的 ...

  2. 洛谷P1352 没有上司的舞会——树形DP

    第一次自己写树形DP的题,发个博客纪念`- 题目来源:P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结 ...

  3. P1352 没有上司的舞会[树形dp]

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

  4. [luogu]P1352 没有上司的舞会[树形DP]

    本Lowbee第一次写树形DP啊,弱...一个变量写错半天没看出来...... 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点 ...

  5. 洛谷 P1352 没有上司的舞会 树形DP板子

    luogu传送门 题目描述: 某大学有n个职员,编号为1~n. 他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司. 现在有个周年庆宴会,宴会每邀请来一个职员都会 ...

  6. 洛谷 P1352 没有上司的舞会(树形 DP)

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

  7. 『没有上司的舞会 树形DP』

    树形DP入门 有些时候,我们需要在树形结构上进行动态规划来求解最优解. 例如,给定一颗\(N\)个节点的树(通常是无根树,即有\(N-1\)条无向边),我们可以选择任意节点作为根节点从而定义出每一颗子 ...

  8. CodeVS1380 没有上司的舞会 [树形DP]

    题目传送门 没有上司的舞会 题目描述 Description Ural大学有N个职员,编号为1~N.他们有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.每个职员有一个 ...

  9. 没有上司的舞会 树形dp

    题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri, ...

随机推荐

  1. java集合: List、Set、Map总结 + HashMap/Hashtable 差别

    List:(有序,能够反复)通过下标索引     ----ArrayList  可变数组,随机查找     ----LinkedList    链表,不论什么位置插入删除快     ----Vecto ...

  2. js阻碍DOM加载

    今天用谷歌做了个小测试 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  3. user agent stylesheet 解决方法

    写了一个写了一个页面字体一直是加粗.原来是 strong,b{ user agent stylesheet font-weight:bold; } 引起的 解决方法:又一次定义 strong,b{ f ...

  4. 【转】Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法

    重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码, 于是就会用到Surfa ...

  5. 使用Vitamio插件显示花屏

    Vitamio是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染. 使用vitamio进行播放器的开发非常便捷,使用vitamio的解码,自己编写播放器界 ...

  6. bzoj1143: [CTSC2008]祭祀river && bzoj27182718: [Violet 4]毕业旅行

    其实我至今不懂为啥强联通缩点判入度会错... 然后这个求的和之前那道组合数学一样,就是最长反链=最小链覆盖=最大独立集. #include<cstdio> #include<iost ...

  7. Codeforces Round #367 (Div. 2) 套题

    吐槽:只能说是上分好场,可惜没打,唉 A:Beru-taxi (水题,取最小值) #include <cstdio> #include <cstring> #include & ...

  8. jsp ajax 数据库Demo

    转自:http://blog.csdn.net/rushkid02/article/details/7515058 下面介绍JSP前台表单内容通过Ajax异步提交到后台Servlet进行校验(校验方式 ...

  9. PCB genesis方槽加内角槽孔实现方法

    一.为什么方槽孔加内角孔 如下图,客户来的方槽或Slot槽有内角尺寸要求,通常直接钻一个Slot槽孔内角是不能满足客户要求的,这时我们做CAM的需采用小钻刀进行处理.加内角孔或内角槽的方式进行处理了. ...

  10. ACM_Mystery

    Mystery Time Limit: 2000/1000ms (Java/Others) Problem Description: No Description Input: The first l ...