ZOJ 3527 树形DP(章鱼图DP)
来源:互联网 发布:手机淘宝6.5.1版本 编辑:程序博客网 时间:2024/04/29 09:00
题意
有N个村庄,每个村庄有一定的信仰值,占领村庄可以得到信仰值,每个村庄有一个关联村庄,同时占领关联村庄可以得到加成(可能为负),问占领一些村庄,最多可以得到多少信仰值
题解
这个DP已经不能算是树形DP了,因为有环。不过有趣的是环只有一个(可能有多个环,但是不可能存在环套环)。这样的话我们便可以破环进行DP。
如果画一下图的话可以发现这个图很像一只章鱼,我们进行DP的话,可以首先从触手的位置开始,我们可以首先从触手尖端开始DP(触手尖端为入度为0的点),一直DP到环(环上的点即便减去触手入度也不为0)。对于环上的点,我们要分情况进行DP(因为DP只能用于有向无环图),我们可以将环剪开。对于剪开的位置,我们可以选择选,可以选择不选,于是我们可以开两个DP数组分别讨论。
最后再将两个数组合并,同时将最大信仰值增加到ANS上。需要注意的是,可能有多条章鱼,所以需要进行多次DP,求总和。
注意事项
ZOJ莫名其妙的内存分配机制。。Queue在主函数循环内声明直接TLE。。声明为全局变量2700ms,声明到函数里直接600MS。。终于明白BFS为什么要开一个函数去写了。。
代码
#include <iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<cmath>#include<queue>#include<string>#include<set>#include<map>#include<bitset>#include<stack>#include<string>#define UP(i,l,h) for(int i=l;i<h;i++)#define DOWN(i,h,l) for(int i=h-1;i>=l;i--)#define W(a) while(a)#define MEM(a,b) memset(a,b,sizeof(a))#define LL long long#define INF 0x3f3f3f3f3f3f3f3f#define MAXN 120050#define MOD 1000000007#define EPS 1e-3#define int LLusing namespace std;int f[MAXN],g[MAXN],xnext[MAXN],in[MAXN],dp[MAXN][2],dp1[MAXN][2],p[MAXN];int num;bool vis[MAXN];queue<int> q;void dfs(int u){ p[++num]=u; vis[u]=true; int t=xnext[u]; if(vis[t]) return ; dfs(t);}main() { int n; W(~scanf("%lld",&n)) { W(!q.empty()) q.pop(); MEM(in,0); MEM(dp,0); MEM(dp1,0); MEM(vis,false); UP(i,1,n+1) { scanf("%lld%lld%lld",&f[i],&g[i],&xnext[i]); in[xnext[i]]++; } UP(i,1,n+1){ dp[i][1]=f[i]; if(in[i]==0){ q.push(i); in[i]--; } } W(!q.empty()){ int r=q.front(); q.pop(); vis[r]=true; int k=xnext[r]; dp[k][0]+=max(dp[r][0],dp[r][1]); dp[k][1]+=max(dp[r][0],dp[r][1]+g[r]); if(--in[k]==0) q.push(k); } int ans=0; UP(j,1,n+1){ if(!vis[j]){ num=0; dfs(j); memcpy(dp1,dp,sizeof(dp)); dp1[p[2]][0]+=dp1[p[1]][0]; dp1[p[2]][1]+=dp1[p[1]][0]; UP(i,3,num+1){ dp1[p[i]][0]+=max(dp1[p[i-1]][0],dp1[p[i-1]][1]); dp1[p[i]][1]+=max(dp1[p[i-1]][0],dp1[p[i-1]][1]+g[p[i-1]]); } dp[p[2]][0]+=dp[p[1]][1]; dp[p[2]][1]+=dp[p[1]][1]+g[p[1]]; UP(i,3,num+1){ dp[p[i]][0]+=max(dp[p[i-1]][0],dp[p[i-1]][1]); dp[p[i]][1]+=max(dp[p[i-1]][0],dp[p[i-1]][1]+g[p[i-1]]); } dp[p[num]][1]+=g[p[num]]; int tmp=0; UP(i,1,num+1){ dp[p[i]][0]=max(dp[p[i]][0],dp1[p[i]][0]); dp[p[i]][1]=max(dp[p[i]][1],dp1[p[i]][1]); tmp=max(dp[p[i]][0],dp[p[i]][1]); } ans+=tmp; } } printf("%lld\n",ans); }}
阅读全文
0 0
- ZOJ 3527 树形DP(章鱼图DP)
- 树形DP zoj 3527
- ZOJ-3626(树形DP)
- ZOJ 3949 (树形DP)
- ZOJ 3805 树形dp
- zoj 3626 树形dp
- ZOJ 3949 树形DP
- zoj 3527 带环的树形DP
- ZOJ 3805 Machine(树形DP)
- ZOJ 3527 Shinryaku! Kero Musume 【树形DP[带简单环]】
- ZOJ 3201 Tree of Tree(树形DP)
- zoj-3626 Treasure Hunt I (树形dp)
- zoj 3201 Tree of Tree(树形背包dp)
- zoj 3626 Treasure Hunt I (树形dp)
- ZOJ 3626 Treasure Hunt I(树形dp)
- ZOJ 3626 Treasure Hunt I (树形dp)
- ZOJ 3949 Edge to the Root(树形DP)
- ZOJ 3805 Machine(搜索+技巧)【树形DP模板】
- 常见正则表达式汇总【一】
- 常用正则表达式(2)
- 微软为啥让免费升Win10?
- JDK和Tomcat配置
- CCIE-MPLS VPN-实验手册(中卷)
- ZOJ 3527 树形DP(章鱼图DP)
- lombok的简单介绍(2)
- 【★】百度网盘背后的真实策略!
- 即时作图新工具—ProcessOn【推荐】…
- PCL:1.7.2使用时的一个问题(core dumped与-std=c++11)
- ssm框架的搭建
- mysql分页查询语句怎么写?
- CCIE-MPLS VPN-实验手册(下卷)
- 洛谷P1297--网线切割_题解