【JZOJ4771】【NOIP2016提高A组模拟9.9】爬山
题目描述
国家一级爬山运动员h10今天获得了一张有着密密麻麻标记的地图,在好奇心的驱使下,他又踏上了去爬山的路。
对于爬山,h10有一个原则,那就是不走回头路,于是他把地图上的所有边都标记成了有向边。他决定从点S出发,每到达一个新的节点他就可以获得一定的成就值。同时h10又是一个很珍惜时间的运动员,他不希望这次爬山的成就值白白浪费,所以最后他一定要在一个存档点停下,保存自己的成就值。
请你计算出在此次爬山运动中h10能够得到的最大成就值。保证h10能走到存档点。
输入
第一行两个整数 N,M,表示点数和边数。
接下来 M 行,每行两个整数 u,v,表示u到v有一条有向边(没有自环)。
第 M+2 行 N 个正整数,表示每个点的成就值。
接下来一行两个整数 S,p,表示出发点和存档点个数。
下面一行 p 个整数,表示存档点。
输出
一个正整数,表示最大成就值。
样例输入
5 7
5 1
3 1
2 5
3 5
4 3
4 2
4 5
7 6 3 2 2
4 3
1 5 2
样例输出
17
数据范围
对于 30% 的数据, N,M≤1000,并且地图为有向无环图。
对于 100% 的数据, N,M≤500000。(数据有梯度,注意答案的大小)
解法
这道题模型很明显,考虑图是一个DAG(有向无环图)的时候,拓扑排序上动态规划即可。
对于有环的情况,发现一个环的贡献是这个环上所有点的权值之和。
所以使用强连通分量把每个环都缩成一个点。
再使用拓扑排序上动态规划即可。
※手写栈需要
代码
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define ln(x,y) ll(log(x)/log(y))
#define sqr(x) ((x)*(x))
using namespace std;
const char* fin="aP2.in";
const char* fout="aP2.out";
const ll inf=0x7fffffff;
const ll maxn=500007,maxm=maxn*2;
ll n,m,i,j,k,st,En,tot,num;
ll a[maxn],fi[maxn],ne[maxm],la[maxm];
ll stack[maxn],dfn[maxn],low[maxn],fa[maxn];
ll ru[maxn];
ll b[maxn];
ll f[maxn],ans;
ll cz[maxn];
bool bz[maxn],en[maxn];
ll read(){
ll x=0;
char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
void add_line(ll a,ll b){
tot++;
ne[tot]=fi[a];
la[tot]=b;
fi[a]=tot;
}
struct handstack{
ll i,j,k,v;
}hs[maxn];
int hst=0;
void handdfs(ll v){
hs[++hst].v=v;
hs[hst].i=0;
while (hst){
if (hs[hst].i){
if (hs[hst].k){
if (!dfn[la[hs[hst].k]]) {
hs[hst+1].v=la[hs[hst].k];
hs[hst+1].i=0;
hst++;
continue;
}else if (bz[la[hs[hst].k]]) low[hs[hst].v]=min(low[la[hs[hst].k]],low[hs[hst].v]);
hs[hst].k=ne[hs[hst].k];
}else{
if (low[hs[hst].v]==dfn[hs[hst].v]){
while (stack[0]>hs[hst].j) {
for (hs[hst].k=fi[stack[stack[0]]];hs[hst].k;hs[hst].k=ne[hs[hst].k]) add_line(hs[hst].v,la[hs[hst].k]);
fa[stack[stack[0]]]=hs[hst].v;
a[fa[stack[stack[0]]]]+=a[stack[stack[0]]];
bz[stack[stack[0]--]]=false;
}
fa[stack[stack[0]]]=hs[hst].v;
bz[stack[stack[0]--]]=false;
}
hst--;
}
}else{
hs[hst].i=1;
dfn[hs[hst].v]=low[hs[hst].v]=++num;
bz[stack[hs[hst].j=++stack[0]]=hs[hst].v]=true;
hs[hst].k=fi[hs[hst].v];
}
}
}
void dfs(ll v){
ll i,j,k;
dfn[v]=low[v]=++num;
bz[stack[j=++stack[0]]=v]=true;
for (k=fi[v];k;k=ne[k])
if (!dfn[la[k]]) {
dfs(la[k]);
low[v]=min(low[la[k]],low[v]);
}else if (bz[la[k]]) low[v]=min(dfn[la[k]],low[v]);
if (low[v]==dfn[v]){
while (stack[0]>j) {
for (k=fi[stack[stack[0]]];k;k=ne[k]) add_line(v,la[k]);
fa[stack[stack[0]]]=v;
a[fa[stack[stack[0]]]]+=a[stack[stack[0]]];
bz[stack[stack[0]--]]=false;
}
fa[stack[stack[0]]]=v;
bz[stack[stack[0]--]]=false;
}
}
void topsort(){
ll i,j,k,head=0,tail=0;
for (i=1;i<=n;i++){
if (fa[i] && i==fa[i]) for (k=fi[i];k;k=ne[k]){
if (/*cz[fa[la[k]]]<i && */fa[la[k]]!=i) ru[fa[la[k]]]++/*,cz[fa[la[k]]]=i*/;
}
}
for (i=1;i<=n;i++) if (!ru[i] && fa[i]==i) {
b[++tail]=i;
f[i]=a[i];
break;
}
while (head++<tail){
if (en[b[head]]) ans=max(ans,f[b[head]]);
for (k=fi[b[head]];k;k=ne[k]) if (fa[la[k]]!=b[head]){
i=fa[la[k]];
f[i]=max(f[i],f[b[head]]+a[i]);
if (--ru[i]==0) b[++tail]=i;
}
}
}
int main(){
n=read();m=read();
for (i=1;i<=m;i++){
j=read();k=read();
add_line(j,k);
}
for (i=1;i<=n;i++) a[i]=read();
st=read();En=read();
handdfs(st);
for (i=1;i<=En;i++) j=read(),en[fa[j]]=true;
topsort();
printf("%lld",ans);
return 0;
}
【JZOJ4771】【NOIP2016提高A组模拟9.9】爬山的更多相关文章
- JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数
4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms Memory Limits: 262144 KB Detailed ...
- 【NOIP2016提高A组模拟9.14】数列编辑器
题目 分析 比赛上,没有注意到询问只询问光标前面,于是只打了个暴力. 因为询问只询问光标前面,首先,当光标向后每移动到一个位置,顺便将这个位置的前缀和,和最大前缀和求出来. 总之,模拟 #includ ...
- 【NOIP2016提高A组模拟9.24】总结
第一题纯模拟,结果那个出题人脑子似乎进水了,空间限制开了1G!!! 导致我捉摸了半天为什么空间要开那么大,最后只能得出上面的结论. 第二题是个矩阵快速幂,比赛上我没把递推式求出来,但是根据各种乱搞,得 ...
- 【JZOJ4746】【NOIP2016提高A组模拟9.3】树塔狂想曲
题目描述 相信大家都在长训班学过树塔问题,题目很简单求最大化一个三角形数塔从上往下走的路径和.走的规则是:(i,j)号点只能走向(i+1,j)或者(i+1,j+1).如下图是一个数塔,映射到该数塔上行 ...
- 【JZOJ4745】【NOIP2016提高A组模拟9.3】看电影
题目描述 听说NOIP2016大家都考得不错,于是CCF奖励省常中了 K 张变形金刚5的电影票奖励OI队的同学去看电影.可是省常中OI队的同学们共有 N(N >= K)人.于是机智的你想到了一个 ...
- 【JZOJ4803】【NOIP2016提高A组模拟9.28】求导
题目描述 输入 输出 样例输入 2x^2+3x+1 样例输出 4x+3 数据范围 样例解释 求导的意思: 多项式是由若干个单项式构成的 单项式的一般形式是ax^b,其中ab都是常数,x是自变量 对于单 ...
- 【JZOJ4787】【NOIP2016提高A组模拟9.17】数格子
题目描述 输入 输出 样例输入 1 10000 3 10000 5 10000 0 0 样例输出 1 11 95 数据范围 每个测试点数据组数不超过10组 解法 状态压缩动态规划. 设f[i][j]表 ...
- [jzoj 4668] [NOIP2016提高A组模拟7.19] 腐败 解题报告(质数分类+慢速乘)
题目链接: http://172.16.0.132/senior/#main/show/4668 题目: 题解: 考虑把A数组里的每个元素分解质因数,对于每个质因数开一个vector存一下包含这个质因 ...
- [jzoj 4722] [NOIP2016提高A组模拟8.21] 跳楼机 解题报告 (spfa+同余)
题目链接: http://172.16.0.132/senior/#main/show/4722 题目: DJL为了避免成为一只咸鱼,来找srwudi学习压代码的技巧.Srwudi的家是一幢h层的摩天 ...
随机推荐
- hibernate 多表关联外键问题无法截断表的解决办法
目前只有一个办法 就是手动清除其他表的外键关联,然后在做一个小swing单独去操作这个表,而不运行主控方相关的代码 当web运行后,外键会再次设置好
- netcore进程内(InProcess)托管和进程外(out-of-Process)托管
当一个 ASP.NET Core 应用程序执行的时候,.NET 运行时会去查找 Main()方法,因为它是这个应用程序的起点. 然后,Main()方法调用静态类WebHost中的静态方法CreateD ...
- python-基础-字符串-列表-元祖-字典
1 字符串 1.1 下标和切片 1.2 切片 1.3 字符串常见操作 如有字符串mystr = 'hello world itcast and itcastcpp',以下是常见的操作 <1> ...
- Luogu P2292 [HNOI2004]L语言(Trie+dp)
P2292 [HNOI2004]L语言 题面 题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章 \(T\) 是由若干小写字母构成. ...
- global.fun.php
<?php /** 所有公共函数文件*/ /** 序列化*/function _serialize($obj){ return base64_encode(gzcompress( ...
- Spring配置xml自动提示——转载https://blog.csdn.net/sinat_18474835/article/details/79370629
以Spring2.0为例: 下载地址: Csdn: http://download.csdn.net/download/hh775313602/9812757 没积分的可以去百度网盘下载,我已共享: ...
- I Hate It HDU - 1754 (线段树)
注意点:scanf中使用%c时,会读取空格和回车,所以在%c之前要有一个空格 ( 或者直接使用%s也行,%s会忽略空格和回车 ).具体见下面的代码: #include<iostream> ...
- Java问题解读系列之基础相关---含继承时的执行顺序
今天来研究一下含继承.静态成员.非静态成员时Java程序的执行顺序: 一.不含继承,含有静态变量.静态代码块 创建一个子类,该类包含静态变量.静态代码块.静态方法.构造方法 /** * @create ...
- 常见的HTML标签的嵌套规则
众所周知,HTML标签有两类: 块级元素div.h1~h6.address.blockquote.center.dir.dl.dt.dd.fieldset.form.hr.isindex.menu.n ...
- 大数据概念(4V)