ZOJ3527
题意:给你一个有向图,一共N个顶点,且每个顶点只有一个前驱或后继,在顶点上建立圣地,那么就可以获得一个信仰值,如果在这个顶点的后继节点上也建立圣地,那么将改变一定的信仰值,求解能获取的最大信仰值。
思路:好吧,这题一点思路都没有,本来题目就做的比别人少,树状DP什么的,更是少,这次要不是准备好好研究下DP问题,估计想都没想过去接触这种东西,只怪自己太懒了。题目是求最大值的,所以考虑要不要在这个点上新建圣地问题,那么就分两种情况了,所以取其中最大的值就行,由于题目给的是简单环,所以之前要进行处理下,n个顶点,n条边,所有先处理环上的树枝节点,然后再对环做DP就可以。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
typedef long long LL;
const int MAX=100010; LL in_degree[MAX],sec[MAX],g[MAX],f[MAX],q[MAX];
LL DP[MAX][2],re[MAX][2];
bool flag[MAX];
LL n,k;
LL sum;
int i,j; LL ss(LL f,LL now,LL DP[][2],LL flag)
{
LL i,j,k;
k=now;
i=sec[k];
while(i!=f)
{
DP[i][0]+=max(DP[k][0],DP[k][1]);
DP[i][1]+=max(DP[k][0],DP[k][1]+g[k]);
k=sec[k];
i=sec[k];
}
if(flag) DP[k][1]+=g[k];
return max(DP[k][0],DP[k][1]);
}
LL solve(LL now)
{
LL i,j,xx,k;
k=now;
i=sec[k];
re[i][0]+=DP[k][0];
re[i][1]+=DP[k][0];
j=ss(now,i,re,0); DP[i][0]+=DP[k][1];
DP[i][1]+=DP[k][1]+g[k];
xx=ss(now,i,DP,1);
return max(j,xx);
}
void branch()
{
int x;
for(x=0,i=1; i<=n; i++)
{
DP[i][1]=f[i];
if(!in_degree[i])
q[x++]=i;
}
while(x)
{
k=q[--x]; flag[k]=true;
i=sec[k]; DP[i][0]+=max(DP[k][0],DP[k][1]);
DP[i][1]+=max(DP[k][0],DP[k][1]+g[k]); if(--in_degree[i]==0LL)
q[x++]=i;
}
}
LL ring()
{
memcpy(re,DP,sizeof(DP)); for(sum=0,i=1; i<=n; i++)
{
if(!flag[i])
{
sum+=solve(i);
flag[i]=true;
for(j=sec[i]; j!=i; j=sec[j])
flag[j]=true;
}
}
return sum;
} int main()
{
while(scanf("%lld",&n)!=EOF)
{
memset(in_degree,0,sizeof(in_degree));
memset(DP,0,sizeof(DP));
memset(flag,false,sizeof(flag)); for(i=1; i<=n; i++)
{
scanf("%lld%lld%lld",&f[i],&g[i],&sec[i]);
in_degree[sec[i]]++;
} branch(); //将树枝节点分离并且计算
printf("%lld\n",ring()); //另外对环上的所有点DP
}
return 0;
}
ZOJ3527的更多相关文章
随机推荐
- 10条PHP高级技巧
1.使用一个SQL注射备忘单 一个基本的原则就是,永远不要相信用户提交的数据. 另一个规则就是,在你发送或者存储数据时对它进行转义(escape). 可以总结为:filter input, escap ...
- 转:Ubuntu12.04 LTS 使用心得-开机挂载其他分区
1.在/media目录下创建好用来关联你要挂载的分区的文件夹(相当于一个虚拟目录/挂载点,链接/映射到你要挂载的盘符去) 我要挂载4个分区,所以创建了四个挂载点,名字随便取,只要你自己认的出来哪个对应 ...
- Jersey Politics
poj2454:http://poj.org/problem?id=2454 题意:给你3*k个数,然后让你分成三堆,使得至少其中的两堆中的数字之和大于500*k.题解:这道题一开始我并不知道怎么做, ...
- poj 2432 Around the world bfs+哈希
由于每个点的状态包含走过来的距离,所以要存二维的状态,但是状态总量太多,所以可以用哈希来搞. 那么就是bfs最短路,哈希记录状态了. #include <iostream> #includ ...
- Codeforces 716A Crazy Computer 【模拟】 (Codeforces Round #372 (Div. 2))
A. Crazy Computer time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 数据结构——UVA 1600 机器人巡逻
描述 A robot has to patrol around a rectangular area which is in a form of mxn grid (m rows and n colu ...
- Json.Net学习笔记(十) 保持对象引用
更多内容见这里:http://www.cnblogs.com/wuyifu/archive/2013/09/03/3299784.html 默认情况下,Json.Net将通过对象的值来序列化它遇到的所 ...
- WEB性能测试:你应该带上VisualStudio2010
原文地址:http://www.16aspx.com/Article/62 在Web性能测试方面,增加了循环(Loops)和条件(Conditions),让开发人员可以为他们的应用程序写出更复杂,更智 ...
- linux0.12 解决编译问题常用命令
解决编译问题时,经常需要修改所有的Makefile,特别定义了下面几条命令方便修改. function msed() { find -name "Makefile" -exec s ...
- DNA Sequence - POJ 2778(AC自动机+矩阵乘法)
题目大意:DNA序列是有 ATGC 组成的,现在知道一些动物的遗传片段有害的,那么如果给出这些有害的片段,能否求出来所有长度为 N 的基因中有多少是不包含这些有害片段的. 分析:也是断断续续做了一 ...