zoj3734
来源:互联网 发布:sim800传输数据 编辑:程序博客网 时间:2024/06/05 16:33
题意:一棵有根树,每个节点都有一个value值和属性(LICK或是 CANDLE)。你可以通过反转一些点的属性,反转一个点时候,它的整个子树都会被反转属性。有些点反转消耗代价为X,有些为Y。你的目标的是使得LICK的value和最大。
解法:13年长沙区域赛一道题,感情当时都没有做到这道题。状态ans[i][0/1]分别表示此点的子树LICK最多能比CANDLE多多少和少多少的值。状态转移见代码。
代码:
/******************************************************* @author:xiefubao*******************************************************/#pragma comment(linker, "/STACK:102400000,102400000")#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <map>#include <set>#include <stack>#include <string.h>//freopen ("in.txt" , "r" , stdin);using namespace std;#define eps 1e-8#define zero(_) (_<=eps)const double pi=acos(-1.0);typedef long long LL;const int Max=50010;const LL INF=0x3FFFFFFF;int n,x,y;vector<int> vec[Max];int value[Max];int ans[Max][2];bool flip[Max];void dfs(int t,int st){ st+=flip[t]; if(st&1) value[t]=-value[t]; ans[t][0]=value[t]; ans[t][1]=-value[t]; for(int i=0;i<vec[t].size();i++) { dfs(vec[t][i],st); int p=vec[t][i]; ans[t][0]+=max(ans[p][0],ans[p][1]-(flip[p]?y:x)); ans[t][1]+=max(ans[p][1],ans[p][0]-(flip[p]?y:x)); }}int main(){ while(cin>>n>>x>>y) { memset(ans,0,sizeof ans); for(int i=0; i<=n; i++) vec[i].clear(); for(int i=1; i<=n; i++) { int v,f,s,p; scanf("%d%d%d%d",&value[i],&f,&s,&p); flip[i]=s; if(p) value[i]=-value[i]; vec[f].push_back(i); } dfs(0,0); if(ans[0][0]<0) puts("HAHAHAOMG"); else cout<<ans[0][0]<<endl; } return 0;}
0 0
- zoj3734
- ZOJ3734 树形DP
- 2.1.7可变类型与不可变类型
- iOS中浅拷贝和深拷贝的区别
- ReentrantLock和synchronized两种锁定机制的对比
- java 反射机制详解
- 浅谈算法和数据结构(3):合并排序
- zoj3734
- Oracle 12c agent install for linux
- VS2010x64 无法启动此程序,因为计算机中丢失MSVCR100D.dll和LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 猪八ms
- 算法之贪心算法
- Java代码生成二维码图片
- 性能测试的概念和分类
- Apk伪加密实现与破解JAVA源码
- ProtoBuf开发者指南