hdu4799 树型DP

题意:若干微博账户形成了一个转发树(即一个有根树)。每个账户有自己的价值,每个账户也有自己的态度(赞或蜡烛)。如果一个账户的态度是“赞”,它的价值就会被加到“赞”的一边,反之亦然。Edward可以从“赞”的一边拿出X 的价值去翻转一个账户,即把它的态度换到相反的一边。但是Edward 发现,有的账户已经被别人翻转过了,对于这些账户,Edward就要花费Y的价值去翻转它们。一旦一个账户被翻转了一次,它的所有子账户也会被翻转一次。求“赞”的一边的价值总数与“蜡烛”一边的价值总数的最大差值。若最大差值为负数则输出“HAHAHAOMG”。

输入:N个账户,X flip一个没有fliped的账户需要的花费,Y flip一个已经fliped的账户需要的花费。

四个数:账户价值,转发来源,是否要被flip(1表示要),被flip之前的状态(1表示蜡烛,0表示like)

题解:说实话觉得特别绕,dp[n][2]两个状态一个表示翻转能得到的最大价值,一个表示不翻转能得到的最大价值。翻转的花费在父节点那一层计算更好算,因为最终的0节点是无法操作的,所以在那算很方便。有个trick就是初始就被转过的点的影响依然在子节点中,所以要用sta标记,,,,

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 #include <cmath>
 7 using namespace std;
 8 typedef long long ll;
 9 const ll INF = 1000000000000000000ll + 10 ;
10 const double eps = 1e-8;
11 const int maxn = 5e4 + 10;
12 const double PI = acos(-1);
13 int dp[maxn][2],head[maxn],val[maxn],ss[maxn],ff[maxn],cnt;
14 bool sta;
15 struct st{
16     int to,nxt;
17 }edge[maxn*2];
18 int n,x,y;
19 void add(int u,int v){
20     edge[cnt].to = v;
21     edge[cnt].nxt = head[u];
22     head[u] = cnt;
23     cnt++;
24 }
25 void dfs(int u,int pre){
26     if(ss[u]) sta = !sta;
27     if(sta) val[u] = -val[u];
28     dp[u][0] = val[u];
29     dp[u][1] = -val[u];
30     for(int i = head[u];i != -1;i = edge[i].nxt){
31         int v = edge[i].to;
32         if(v == pre) continue;
33         dfs(v,u);
34         dp[u][0] += max(dp[v][0],dp[v][1] - (ss[v]?y:x));
35         dp[u][1] += max(dp[v][1],dp[v][0] - (ss[v]?y:x));
36     }
37     if(ss[u]) sta = !sta;
38 }
39 void init(){
40     cnt = 0;
41     memset(dp,0,sizeof(dp));
42     memset(head,-1,sizeof(head));
43 }
44 int main()
45 {
46   //  freopen("in.txt","r",stdin);
47     while(~scanf("%d%d%d",&n,&x,&y)){
48         init();
49         int fr;
50         for(int i = 1;i <= n;i++){
51             scanf("%d%d%d%d",&val[i],&fr,&ss[i],&ff[i]);
52             if(ff[i]) val[i] = -val[i];
53             add(fr,i);
54         }
55         sta = false;
56         dfs(0,-1);
57         if(dp[0][0] < 0) cout<<"HAHAHAOMG"<<endl;
58         else  printf("%d\n",dp[0][0]);
59     }
60         return 0;
61 }
时间: 2024-11-06 01:47:57

hdu4799 树型DP的相关文章

HDU1561 The more, The Better(树型DP)

题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏. 题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP: dp[u][m]表示以u结点为根的子树攻克m个结点的最大价值 但是这样转移太难了,根是从每个孩子通过各自分配若干的城堡去攻克转移的,一个排列组合数,阶乘,是指数级的时间复杂度! 看了题解,原来这是依赖背包,没看背包九讲..不过网上的博客似乎没说清楚,事实上这个状态应该是三个维度来表示: dp[u][

POJ3659 Cell Phone Network(树上最小支配集:树型DP)

题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. 树上的每个结点作为其子树的根可以有三个状态: 不属于支配集且还没被支配 不属于支配集但被其孩子支配 属于支配集 那么就是用dp[u][1\2\3]来表示动归的状态. 123转移该怎么转移就怎么转移..最后的结果就是min(dp[root][2],dp[root][3]). 要注意的是对于有些结点前2

HDU_1561_The more, The Better_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7031    Accepted Submission(s): 4121 Problem Description ACboy很喜欢玩一种战略游戏,

HDU_1520_Anniversary party_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8233    Accepted Submission(s): 3574 Problem Description There is going to b

二叉苹果树(树型DP+背包)

二叉苹果树 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点).这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来描述一根树枝的位置.下面是一颗有4个树枝的树: 2   5 \  / 3  4 \  / 1 现在这颗树枝条太多了,需要剪枝.但是一些树枝上长有苹果. 给定需要保留的树枝数量,求出最多能留住多少苹果. 程序名:apple 输入格式: 第1行2个数,N和Q(1<=Q<= N,1<N<=

HDU_1011_Starship Troopers_树型dp

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 16276    Accepted Submission(s): 4335 Problem Description You, the leader o

【HDOJ 5834】Magic boy Bi Luo with his excited tree(树型DP)

[HDOJ 5834]Magic boy Bi Luo with his excited tree(树型DP) Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Bi Luo is a magic boy, he also has a migic tree,

【POJ 2486】 Apple Tree(树型dp)

[POJ 2486] Apple Tree(树型dp) Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8981   Accepted: 2990 Description Wshxzt is a lovely girl. She likes apple very much. One day HX takes her to an apple tree. There are N nodes in the tree. Each

[HAOI2010][BZOJ2427] 软件安装|tarjan|树型dp

2427: [HAOI2010]软件安装 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 463  Solved: 194[Submit][Status][Discuss] Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). 但是现在有个问题:软件之间存在依赖关系,即软件i只有在安装了软件j(