【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层的摩天 ...
随机推荐
- 【codeforces 500D】New Year Santa Network
[题目链接]:http://codeforces.com/problemset/problem/500/D [题意] 有n个节点构成一棵树; 让你随机地选取3个不同的点a,b,c; 然后计算dis(a ...
- day19 作业
今日作业 1.什么是对象?什么是类? 对象:特征和技能的结合体 类:一系列对象 相同的特征和技能的结合体 2.绑定方法的有什么特点 对象调用类内部的函数 称之为绑定方法,特点: 不同的对象调用该绑定方 ...
- html常用标签详解2-图片标签详解
<img /> 1.图片标签的属性 图片标签属于行内块元素,它自身的属性有一下几个,听我娓娓道来: src:图片资源的路径(resourse),可以使绝对路径,也可以是相对路径 绝对路径: ...
- vue 基本知识
1,内置事件对象event 原生JS事件中是直接通过传入 e 或者 event 就可以获取,但在vue中要传入 $event 才可以获取到内置事件对象 <body> <button ...
- container中的内容 垂直-水平居中
.container{ display: box; display: -webkit-box; -webkit-box-pack: center; -webkit-box-align: center; ...
- PAT甲级——A1059 Prime Factors
Given any positive integer N, you are supposed to find all of its prime factors, and write them in t ...
- Python Flask高级编程之从0到1开发《鱼书》精品项目
Python Flask高级编程之从0到1开发<鱼书>精品项目 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感 ...
- python scikit-learn计算tf-idf词语权重
python的scikit-learn包下有计算tf-idf的api,研究了下做个笔记 1 安装scikit-learn包 sudo pip install scikit-learn 2 中文分 ...
- 2019-4-6-VisualStudio-编码规范工具-2.6-修改当前文件编码
title author date CreateTime categories VisualStudio 编码规范工具 2.6 修改当前文件编码 lindexi 2019-04-06 15:31:53 ...
- redis 原生操作 & python操作redis
一.基本介绍 1.简介 Redis是由意大利人Salvatore Sanfilippo(网名:antirez)开发的一款内存高速缓存数据库.Redis全称为:Remote Dictionary Ser ...