bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa

Input
第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号。接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数。接下来一行包含两个整数S、P,S表示市中心的编号,也就是出发的路口。P表示酒吧数目。接下来的一行中有P个整数,表示P个有酒吧的路口的编号
Output
输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。
Sample Input
Sample Output
Hint
50%的输入保证N, M<=3000。所有的输入保证N, M<=500000。每个ATM机中可取的钱数为一个非负整数且不超过4000。输入数据保证你可以从市中心沿着Siruseri的单向的道路到达其中的至少一个酒吧。
觉得这道题和某道noip题(买卖水晶球的题)比较像,这道题似乎不能双向spfa,但是可以先用Tarjan找到强联通分量,然后缩点,这样就是一个有向无环图,就可以进行spfa,在有酒吧的点找最大值。
Code
/**
* bzoj
* Problem#1179
* Accepted
* Time:6280ms
* Memory:56800k
*/
#include<iostream>
#include<fstream>
#include<sstream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<ctime>
#include<map>
#include<stack>
#include<set>
#include<queue>
#include<vector>
#ifndef WIN32
#define AUTO "%lld"
#else
#define AUTO "%I64d"
#endif
using namespace std;
typedef bool boolean;
#define inf 0xfffffff
#define smin(a, b) (a) = min((a), (b))
#define smax(a, b) (a) = max((a), (b))
template<typename T>
inline boolean readInteger(T& u) {
char x;
int aFlag = ;
while(!isdigit((x = getchar())) && x != '-' && x != -);
if(x == -) {
ungetc(x, stdin);
return false;
}
if(x == '-') {
aFlag = -;
x = getchar();
}
for(u = x - ''; isdigit((x = getchar())); u = u * + x - '');
u *= aFlag;
ungetc(x, stdin);
return true;
} ///map template starts
typedef class Edge{
public:
int end;
int next;
Edge(const int end = , const int next = ):end(end), next(next) { }
}Edge; typedef class MapManager{
public:
int ce;
int *h;
Edge *edge;
MapManager() { }
MapManager(int points, int limit):ce() {
h = new int[(const int)(points + )];
edge = new Edge[(const int)(limit + )];
memset(h, , sizeof(int) * (points + ));
}
inline void addEdge(int from, int end) {
edge[++ce] = Edge(end, h[from]);
h[from] = ce;
}
Edge& operator [] (int pos) {
return edge[pos];
}
}MapManager;
#define m_begin(g, i) (g).h[(i)]
///map template ends int n, m, s, p;
int* moneys;
MapManager g;
boolean *rest; inline void init() {
readInteger(n);
readInteger(m);
moneys = new int[(const int)(n + )];
rest = new boolean[(const int)(n + )];
g = MapManager(n, * m);
memset(rest, false, sizeof(boolean) * (n + ));
for(int i = , a, b; i <= m; i++) {
readInteger(a);
readInteger(b);
g.addEdge(a, b);
}
for(int i = ; i <= n; i++)
readInteger(moneys[i]);
readInteger(s);
readInteger(p);
for(int i = , a; i <= p; i++) {
readInteger(a);
rest[a] = true;
}
} int cnt = ;
boolean *visited, *instack;
int* visitID, *exitID;
int *belong;
stack<int> st; inline void getPart(int end) {
int x;
do {
x = st.top();
st.pop();
instack[x] = false;
if(x != end) {
moneys[end] += moneys[x];
rest[end] = rest[x] || rest[end];
}
belong[x] = end;
} while(x != end);
} void tarjan(int node) {
visited[node] = instack[node] = true;
st.push(node);
visitID[node] = exitID[node] = ++cnt;
for(int i = m_begin(g, node); i != ; i = g[i].next) {
int& e = g[i].end;
if(!visited[e]) {
tarjan(e);
smin(exitID[node], exitID[e]);
} else if(instack[e]) {
smin(exitID[node], visitID[e]);
}
}
if(visitID[node] == exitID[node]) getPart(node);
} MapManager ng;
inline void build() {
visited = new boolean[(const int)(n + )];
instack = new boolean[(const int)(n + )];
visitID = new int[(const int)(n + )];
exitID = new int[(const int)(n + )];
belong = new int[(const int)(n + )];
memset(visited, false, sizeof(boolean) * (n + ));
memset(instack, false, sizeof(boolean) * (n + ));
ng = MapManager(n, m);
tarjan(s);
for(int i = ; i <= n; i++) {
for(int j = m_begin(g, i); j != ; j = g[j].next) {
int& e = g[j].end;
if(belong[i] == belong[e]) continue;
ng.addEdge(belong[i], belong[e]);
}
}
delete[] instack;
delete[] visitID;
delete[] exitID;
} queue<int> que;
int *f;
inline void spfa() {
f = new int[(const int)(n + )];
memset(f, , sizeof(int) * (n + ));
memset(visited, false, sizeof(boolean) * (n + ));
que.push(belong[s]);
f[belong[s]] = moneys[belong[s]];
while(!que.empty()) {
int e = que.front();
que.pop();
visited[e] = false;
for(int i = m_begin(ng, e); i != ; i = ng[i].next) {
int eu = ng[i].end;
if(belong[eu] != eu || belong[eu] == belong[e]) continue;
if(f[eu] < f[e] + moneys[eu]) {
f[eu] = f[e] + moneys[eu];
if(!visited[eu]) {
que.push(eu);
visited[eu] = true;
}
}
}
}
} inline void solve() {
build();
spfa();
int res = ;
for(int i = ; i <= n; i++) {
if(belong[i] == i && rest[i]) {
smax(res, f[i]);
}
}
printf("%d", res);
} int main() {
init();
solve();
return ;
}
bzoj 1179 [APIO 2009]Atm(APIO水题) - Tarjan - spfa的更多相关文章
- [APIO 2009] Atm
传送门:>Here< 题意:给出一个有向图(有环),每个点有点权.从点S出发,经过每个点Tot可以加上点权,点可以经过多次,然而点权不能重复加多次.先要求走到某个终点E时点权最大.先要求在 ...
- BZOJ 2761: [JLOI2011]不重复数字 水题
2761: [JLOI2011]不重复数字 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2100 Solved: 809 题目连接 http:// ...
- BZOJ 1179 抢掠计划atm (缩点+有向无环图DP)
手动博客搬家: 本文发表于20170716 10:58:18, 原地址https://blog.csdn.net/suncongbo/article/details/81061601 https:// ...
- BZOJ 1968: [Ahoi2005]COMMON 约数研究 水题
1968: [Ahoi2005]COMMON 约数研究 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeO ...
- BZOJ 1303: [CQOI2009]中位数图 【水题】
给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为1~n 的排列. Out ...
- 【BZOJ 1179】[Apio2009]Atm
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] tarjan强连通缩点一下. 然后把缩点之后,每个点的钱的数累加起来. 然后从S出发 开始一边做bfs一遍做dp. 最后输出有酒吧的 ...
- 【GDOI2015】 水题 tarjan缩点
这一题,我当年只会$60$分做法..... 我们考虑对原图跑一波边双,然后缩成一个森林. 对于森林中的每一棵树,我们钦定一个根. 令$siz[x]$表示以$x$为根的子树中,在原图中点的个数. 令当前 ...
- BZOJ 1179 Atm 题解
BZOJ 1179 Atm 题解 SPFA Algorithm Tarjan Algorithm Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来 ...
- BZOJ USACO 银组 水题集锦
最近刷银组刷得好欢快,好像都是水题,在这里吧他们都记录一下吧(都是水题大家一定是道道都虐的把= =)几道比较神奇的题到时再列出来单独讲一下吧= =(其实我会说是BZOJ蹦了无聊再来写的么 = =) [ ...
随机推荐
- iOS判断UIView是否显示在屏幕上
@interface - (BOOL)isDisplayedInScreen; @end @implementation UIView(UIScreenDisplaying) //判断View是否显示 ...
- 内核futex的BUG导致程序hang死问题排查
https://mp.weixin.qq.com/s/sGS-Kw18sDnGEMfQrbPbVw 内核futex的BUG导致程序hang死问题排查 原创: 王领先 58架构师 今天 近日,Had ...
- table的td的1%
使用media-obj和media-bd类似的样式,大多数采用的是display: table-cell(即是table中td)来实现.当然设置display是不够,还要根据情况设置width.如下面 ...
- Servlet----------在 Servlet 中的xml配置
今天弄了大半天,才弄好了,还是请教了别人,主要原因在于把web.xml文件放在了WEB-INF文件夹下面了,正常的情况是在WebRoot下面的. 还有一个,我是在MyEclipse中操作的,起初不知道 ...
- mysql "order by" "distinct" "group by" "having"
本文用到的表结构 create table stu( stu_id int auto_increment primary key, name ) not null, age smallint, cls ...
- 腾讯在线文档发布:实现QQ、微信多平台多人协作编辑
18日,腾讯宣布推出专注多人协作的在线文档产品—腾讯文档,据介绍,腾讯文档是一款支持随时随地创建.编辑的多人协作式在线文档工具,拥有一键翻译.实时股票函数和浏览权限安全可控等功能,以及打通QQ.微信等 ...
- (转)Mybatis insert后返回主键给实体对象(Mysql数据库)
<insert id="insert" parameterType="com.zqgame.game.website.models.Team"> & ...
- iOS设计规范HIG
点击图标大小至少为这么大: Make it easy for people to interact with content and controls by giving each interacti ...
- C#读取Excel,Access数据库
出自:http://blog.csdn.net/limpire/article/details/2599760 使用 OpenRowSet 和 OpenDataSource 访问 Excel 97-2 ...
- 第三章基本的SQl查询语言
---恢复内容开始--- ---恢复内容结束---