树形DP zoj 3527
题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3527
/*以前做过一道类似的题目,但是这次看到 因为的失误没有看到一句话 把这题直接看成网络流,交给队友处理,看了解题报告才发现这题和我以前做过的一道题神似。
在这个时刻请准许我吐槽一下。。。法克油。。
好了 讲下这题的思路:
首先,每个城市只有一个相关的城市。那么我们必然可以得知每个城市的父节点只有一个。
我们可以不去理会 边的方向。
从而我们可以得知,这个图是由M个子图构成,并且每个子图都是由一个环带着一些树枝。我们可以先对树枝进行树状DP。然后对环上的节点进行DP:任选一个节点,
分两种情况讨论,(建或者不建神庙),然后DP,方程是一样的。
DP方程:
dp[i][0] = max(dp[i-1][0],dp[i-1][1]);
dp[i][1] = max(dp[i-1][0],dp[i-1][1]+zhi[i-1]);
*/
//下面是我的code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
#define N 100005
typedef long long lld;
int n,v[N],P[N],num,in[N];
queue<int>Q;
long long dp[N][2],dp1[N][2],zhi[N],fan[N],next[N],ans;
void dfs(int k)
{
int t = next[k];
if(v[t]) return ;
P[++num] = t;
v[t] = 1;
dfs(t);
}
int main()
{
while(~scanf("%d",&n)){
int i,j,k;
int a,b,c;
while(!Q.empty()) Q.pop();
memset(in,0,sizeof(in));
for(i=1;i<=n;i++){
scanf("%lld%lld%lld",&zhi[i],&fan[i],&next[i]);
in[next[i]]++;
}
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++){
dp[i][1] = zhi[i];
if(in[i] == 0){
Q.push(i);
in[i]--;
}
}
while(!Q.empty()){
int t = Q.front();
Q.pop();
k = next[t];
v[t] = 1;
dp[k][0] += max(dp[t][0],dp[t][1]);
dp[k][1] += max(dp[t][0],dp[t][1] + fan[t]);
if(--in[k] == 0) Q.push(k);
}
ans = 0;
int ll = 0;
for(i=1;i<=n;i++){
if(!v[i]){
num = 0;
P[++num] = i;
v[i] = 1;
dfs(i);
memcpy(dp1,dp,sizeof(dp));
dp1[P[2]][0] += dp1[P[1]][0];
dp1[P[2]][1] += dp1[P[1]][0];
for(j=3;j<=num;j++){
dp1[P[j]][0] += max(dp1[P[j-1]][0],dp1[P[j-1]][1]);
dp1[P[j]][1] += max(dp1[P[j-1]][0],dp1[P[j-1]][1]+fan[P[j-1]]);
}
dp[P[2]][0] += dp[P[1]][1];
dp[P[2]][1] += (dp[P[1]][1]+fan[P[1]]);
for(j=3;j<=num;j++){
dp[P[j]][0] += max(dp[P[j-1]][0],dp[P[j-1]][1]);
dp[P[j]][1] += max(dp[P[j-1]][0],dp[P[j-1]][1]+fan[P[j-1]]);
}
dp[P[num]][1] += fan[P[num]];
long long tmp = 0;
for(j=1;j<=num;j++){
dp[P[j]][0] = max(dp[P[j]][0],dp1[P[j]][0]);
dp[P[j]][1] = max(dp[P[j]][1],dp1[P[j]][1]);
tmp = max(tmp,max(dp[P[j]][0],dp[P[j]][1]));
}
ans += tmp;
}
}
printf("%lld\n",ans);
}
return 0;
}
树形DP zoj 3527相关推荐
- ZOJ 3527 树形DP(章鱼图DP)
题意 有N个村庄,每个村庄有一定的信仰值,占领村庄可以得到信仰值,每个村庄有一个关联村庄,同时占领关联村庄可以得到加成(可能为负),问占领一些村庄,最多可以得到多少信仰值 题解 这个DP已经不能算是树 ...
- BNUOJ 52305 Around the World 树形dp
题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52305 Around the World Time Limit: 20000msMemory ...
- [树形dp] Jzoj P5233 概率博弈
Description 小A和小B在玩游戏.这个游戏是这样的: 有一棵n个点的以1为根的有根树,叶子有权值.假设有m个叶子,那么树上每个叶子的权值序列就是一个1->m 的排列. 一开始在1号点有 ...
- fwt优化+树形DP HDU 5909
1 //fwt优化+树形DP HDU 5909 2 //见官方题解 3 // BestCoder Round #88 http://bestcoder.hdu.edu.cn/ 4 5 #include ...
- BZOJ 1040 ZJOI2008 骑士 树形DP
题目大意:给定一个基环树林,每一个点上有权值,要求选择一个权值和最大的点集,要求点集中的随意两个点之间不能直接相连 最大点独立集--考虑到n<=100W,网络流铁定跑不了,于是我们考虑树形DP ...
- POJ 3342 树形DP+Hash
这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算 ...
- [NC15748]旅游 树形dp基础
菜鸡第一次接触树形dp这个东西,不过这个东西还是很好理解的(可能是因为模板题吧) 个人感觉,相比线性dp,树形dp的状态转移方程更加的直观,难点主要是在"树"的结构上比较麻烦. 题 ...
- 容斥 + 树形dp ---- 2021 icpc 沈阳 L Perfect Matchings
题目链接 题目大意: 就是给你一个2n2n2n个点的完全图,从这个图里面抽出2n−12n-12n−1条边,这些边形成一颗树,现在问你剩下的图里面点进行完美匹配有多少种方案? 解题思路: 一开始被完美匹 ...
- 树形dp ---- gym101667 A(贪心 + 树形dp + 两个dp方程组维护)
题目链接 题目大意: 就是一棵5e35e35e3的树,可以选择一些点,放上基站,如果uuu上的基站价值为ddd,那么距离uuu小于等于ddd的点都会被覆盖,问使得整棵树被覆盖需要的最小价值. 解题思路 ...
最新文章
- 简化可视SLAM应用程序的开发
- 2018-3-23Markov 链(笔记一)定义
- 写一个函数返回参数二进制中 1 的个数
- 量化投资 -获取数据(一)入门篇
- vue如何强行停止ajax请求,VueJs和VueResource,从Ajax请求中删除头字段
- windows 下 git 禁用 CRLF 转换 LF
- 通过Ftp put命令上传导致文件损坏的解决办法
- 视频PPT互动问答丨数据库智能运维专题
- android 弹出键盘引起的问题
- L1-034 点赞 (20 分)
- Perforce-Server迁移
- PAT (Basic Level) Practice1028 人口普查
- 深入理解javascript函数定义与函数作用域
- python画图代码大全-简单画图 - python代码库 - 云代码
- java代码混淆工具ProGuard混淆插件
- 干货 | 携程风控数据仓库实践
- 什么是ACL访问控制列表?它们的匹配机制是什么?
- java实现斗地主发牌案例简单易懂
- 【许晓笛】49行代码就能发币?而且EOS连例子都给你了
- (列表,字典练习)寻找班级里面名字最长的人