题面:

Description
Siruseri城中的道路都是单向的。不同的道路由路口连接。按照法律的规定,在每个路口都设立了一个Siruseri银行的ATM取款机。令人奇怪的是,Siruseri的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。 Banditji计划实施Siruseri有史以来最惊天动地的ATM抢劫。他将从市中心出发,沿着单向道路行驶,抢劫所有他途径的ATM机,最终他将在一个酒吧庆祝他的胜利。 使用高超的黑客技术,他获知了每个ATM机中可以掠取的现金数额。他希望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可以经过同一路口或道路任意多次。但只要他抢劫过某个ATM机后,该ATM机里面就不会再有钱了。 例如,假设该城中有6个路口,道路的连接情况如下图所示:

市中心在路口1,由一个入口符号→来标识,那些有酒吧的路口用双圈来表示。每个ATM机中可取的钱数标在了路口的上方。在这个例子中,Banditji能抢劫的现金总数为47,实施的抢劫路线是:1-2-4-1-2-3-5。
Input
第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。
接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号。
接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数。接下来一行包含两个整数S、P,S表示市中心的编号,也就是出发的路口。P表示酒吧数目。接下来的一行中有P个整数,表示P个有酒吧的路口的编号。
Output
输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。
Sample Input
6 7
1 2
2 3
3 5
2 4
4 1
2 6
6 5
10
12
8
16
1
5
1 4
4 3 5 6
Sample Output
47
Hint
50%的输入保证N, M<=3000。
所有的输入保证N, M<=500000。
每个ATM机中可取的钱数为一个非负整数且不超过4000。
输入数据保证你可以从市中心沿着Siruseri的单向的道路到达其中的至少一个酒吧。


题解:

本蒟蒻第一眼看到这个题表示被吓到了,APIO的题目!!!肯定巨难。。。
细读题目你会发现这其实是一道Tarjan缩点,跑最长路的大水题!!!
把环缩成点强行重新建图(变成了DAG),直接暴力SPFA就出来了


空间,常数巨大的代码:

# include <stdio.h>
# include <stdlib.h>
# include <iostream>
# include <string.h>
# include <algorithm>
# include <queue>
using namespace std; # define N 2000001
# define IL inline
# define RG register
# define UN unsigned
# define ll long long
# define oo 2147483647
# define mem(a, b) memset(a, b, sizeof(a))
# define max(a, b) ((a) > (b)) ? (a) : (b)
# define min(a, b) ((a) < (b)) ? (a) : (b) IL int Get(){
RG char c = '!'; RG int num = 0, z = 1;
while(c != '-' && (c > '9' || c < '0')) c = getchar();
if(c == '-') z = -1, c = getchar();
while(c >= '0' && c <= '9') num = num * 10 + c - '0', c = getchar();
return num * z;
} int n, m, ft[N], nt[N], to[N], bg[N], sk[N], isk[N], dfn[N], low[N], cnt, w[N];
int dis[N], ans, num, cnt1, in[N];
queue <int> Q; IL void Add(RG int u, RG int v){
nt[cnt] = ft[u]; to[cnt] = v; ft[u] = cnt++;
} IL void Dfs(RG int u){
low[u] = dfn[u] = ++cnt1;
isk[u] = 1; sk[++sk[0]] = u;
for(RG int e = ft[u]; e != -1; e = nt[e]){
RG int v = to[e];
if(!dfn[v]){
Dfs(v);
low[u] = min(low[v], low[u]);
}
else if(isk[v]) low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]){
RG int v = sk[sk[0]--]; isk[v] = 0;
w[++num] += w[v];
bg[v] = num;
while(u != v){
v = sk[sk[0]--];
isk[v] = 0;
bg[v] = num;
w[num] += w[v];
}
}
} IL void SPFA(RG int s){
in[bg[s]] = 1;
Q.push(bg[s]);
dis[bg[s]] = w[bg[s]];
while(!Q.empty()){
RG int u = Q.front(); Q.pop();
for(RG int e = ft[u]; e != -1; e = nt[e]){
RG int v = to[e];
if(dis[u] + w[v] > dis[v]){
dis[v] = dis[u] + w[v];
if(!in[v]) in[v] = 1, Q.push(v);
}
}
in[u] = 0;
}
} int main(){
mem(ft, -1);
num = n = Get(); m = Get();
for(RG int i = 1; i <= m; i++){
RG int u = Get(), v = Get();
Add(u, v);
}
for(RG int i = 1; i <= n; i++)
w[i] = Get();
for(RG int i = 1; i <= n; i++)
if(!dfn[i]) Dfs(i);
for(RG int i = 1; i <= n; i++)
for(RG int e = ft[i]; e != -1; e = nt[e]){
RG int v = to[e];
if(bg[i] != bg[v]) Add(bg[i], bg[v]);
}
SPFA(Get());
RG int t = Get();
while(t--){
RG int bar = Get();
ans = max(ans, dis[bg[bar]]);
}
printf("%d\n", ans);
return 0;
}

显然我的代码又臭又长,请大佬自行优化

[APIO2009]抢掠计划的更多相关文章

  1. P3627 [APIO2009]抢掠计划

    P3627 [APIO2009]抢掠计划 Tarjan缩点+最短(最长)路 显然的缩点...... 在缩点时,顺便维护每个强连通分量的总权值 缩完点按照惯例建个新图 然后跑一遍spfa最长路,枚举每个 ...

  2. APIO2009 抢掠计划 Tarjan DAG-DP

    APIO2009 抢掠计划 Tarjan spfa/DAG-DP 题面 一道\(Tarjan\)缩点水题.因为可以反复经过节点,所以把一个联通快中的所有路口看做一个整体,缩点后直接跑\(spfa\)或 ...

  3. 题解 P3627 【[APIO2009]抢掠计划】

    咕了四个小时整整一晚上 P3627 [APIO2009] 抢掠计划(https://www.luogu.org/problemnew/show/P3627) 不难看出答案即为该有向图的最长链长度(允许 ...

  4. [APIO2009]抢掠计划(Tarjan,SPFA)

    [APIO2009]抢掠计划 题目描述 Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是, ...

  5. 【洛谷P3627】[APIO2009]抢掠计划

    抢掠计划 题目链接 比较水的缩点模板题,Tarjan缩点,重新建图,记录联通块的钱数.是否有酒吧 DAG上记忆化搜索即可 #include<iostream> #include<cs ...

  6. [APIO2009]抢掠计划 tarjan缩点+spfa BZOJ1179

    题目描述 Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri 的酒吧也都设 ...

  7. [luoguP3627][APIO2009]抢掠计划

    先来看一下题目描述: 题目描述 Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siru ...

  8. Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划

    Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机.令人奇怪的是,Siruseri ...

  9. 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路

    题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...

随机推荐

  1. Nginx日志分析及脚本编写

    在我们日常的运维中,当Nginx服务器正常运行后,我们会经常密切关注Nginx访问日志的相关情况,发现有异常的日志信息需要进行及时处理. 那今天我将跟大家一起来研究和分析Nginx日志,nginx默认 ...

  2. php define和const的区别

    1.使用const使得代码简单易读,const本身就是一个语言结构,而define是一个函数2.const用于类成员变量的定义,一经定义,不可修改.3.Define不可以用于类成员变量的定义,可用于全 ...

  3. php获取今日开始时间戳和结束时间戳

    1.php获取今日开始时间戳和结束时间戳  $beginToday=mktime(0,0,0,date('m'),date('d'),date('Y'));$endToday=mktime(0,0,0 ...

  4. elasticsearch2.3.3安装

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 作者原来搭建的环境是0.95版本 现在升级到2.3.3版本, ...

  5. Android App 压力测试方法(Monkey)

    一.为什么要开展压力测试 a.提高产品的稳定性:b.提高产品的留存率 二.什么时候开展压力测试 a.首轮功能测试通过后:b.下班后的夜间进行 三.7个基础知识(理论部分) 3.1 手动测试场景与自动测 ...

  6. Mysql(一):初识数据库

    一 数据库管理软件的由来 基于我们之前所学,数据要想永久保存,都是保存于文件中,毫无疑问,一个文件仅仅只能存在于某一台机器上. 如果我们暂且忽略直接基于文件来存取数据的效率问题,并且假设程序所有的组件 ...

  7. 变态的IE

    1.IE7及更早版本, unshift()方法总是返回undefined而不是数组的新长度.2.IE8及之前版本, 在catch语句中捕获的错误对象会被添加到执行环境的变量对象, 而不是catch语句 ...

  8. Yii2中DAO

    数据库访问 (DAO) 创建数据库连接 执行 SQL 查询 引用表和列名称 执行事务 复制和读写分离 操纵数据库模式 Yii 包含了一个建立在 PHP PDO 之上的数据访问层 (DAO).DAO为不 ...

  9. 通过Yii来理解MVC

    模型:是表现业务数据.规则和逻辑的对象. 可以通过集成yii\base\Model或者它的子类定义模型类. 基类yii\base\Model支持许多实用的特性: A 属性:表现业务数据,可以像普通类属 ...

  10. Docker镜像的构成__Dockerfile

    相比docker commit来说,Dockerfile的方法会更加自动化,更加方便快捷,而且功能也更强大.拿构建Nginx容器举例. 先创建一个目录 mkdir /opt/docker-file 进 ...