Position:


List

Description

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的单向的道路到达其中的至少一个酒吧。

Solution

先Tarjian缩点,变成一个DAG(有向无环图)不会Tarjan Algorithm的传送门

接下来就好做了:

  1. Dfs直接上,虽然Bzoj不会卡你,可今天考试丧心病狂的数据把我卡成了90
  2. 记忆化搜索,f[x]记录从x走到尾的最大抢钱数,下次再走到这点就可以直接调用,还是比dfs快蛮多。
  3. 也可以跑最短路(Spfa or Dijstra)

Code

Dfs

// <atm.cpp> - Tue Sep 20 08:15:49 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is. #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=100010;
const int MAXM=100010;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int gi() {
register int w=0,q=0;register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')q=1,ch=getchar();
while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
return q?-w:w;
}
struct Tarjan{
static const int N=500010,M=500010;
int n,m,be,tot,_clock,scc;
int ne[M],to[M];bool in[N];vector<int>p[N];
int bar[N],fr[N],low[N],dfn[N],f[N],st[N],s[N],ss[N];
void add(int u,int v){
to[++tot]=v;ne[tot]=fr[u];fr[u]=tot;
}
void Init(){
n=gi(),m=gi();
for(int i=1;i<=m;i++){
int u=gi(),v=gi();add(u,v);
}
for(int i=1;i<=n;i++)ss[i]=gi();
be=gi(),m=gi();
for(int i=1;i<=m;i++)bar[i]=gi();
}
inline void dfs(int x){
dfn[x]=low[x]=++_clock;
st[++tot]=x;in[x]=true;
for(int o=fr[x];o;o=ne[o])
if(!dfn[to[o]])dfs(to[o]),low[x]=min(low[x],low[to[o]]);
else if(in[to[o]])low[x]=min(low[x],low[to[o]]);
if(dfn[x]==low[x]){
scc++;
while(st[tot]!=x){
f[st[tot]]=scc;in[st[tot]]=false;tot--;
}
f[x]=scc;in[x]=false;tot--;
}
}
void src(int x,int now){
if(now<=f[x])return;f[x]=now;
int to=p[x].size();
for(int i=0;i<to;i++)
src(p[x][i],now+s[p[x][i]]);
}
void Work(){
_clock=tot=scc=0;
memset(dfn,0,sizeof(dfn));
memset(in,false,sizeof(in));
for(int i=1;i<=n;i++)
if(!dfn[i])dfs(i);
for(int i=1;i<=n;i++)s[f[i]]+=ss[i];
for(int i=1;i<=n;i++)
for(int o=fr[i];o;o=ne[o]){
if(f[i]==f[to[o]])continue;
p[f[i]].push_back(f[to[o]]);
}
for(int i=1;i<=m;i++)bar[i]=f[bar[i]];
be=f[be];memset(f,0,sizeof(f));
src(be,s[be]);int ans=0;
for(int i=1;i<=m;i++)ans=max(ans,f[bar[i]]);
printf("%d",ans);
}
}Tar;
int main()
{
freopen("atm.in","r",stdin);
freopen("atm.out","w",stdout);
Tar.Init();Tar.Work();
return 0;
}

记忆化搜索

// <atm.cpp> - Tue Sep 20 08:15:49 2016
// This file is made by YJinpeng,created by XuYike's black technology automatically.
// Copyright (C) 2016 ChangJun High School, Inc.
// I don't know what this program is. #include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#define MOD 1000000007
#define INF 1e9
using namespace std;
typedef long long LL;
const int MAXN=100010;
const int MAXM=100010;
inline int max(int &x,int &y) {return x>y?x:y;}
inline int min(int &x,int &y) {return x<y?x:y;}
inline int gi() {
register int w=0,q=0;register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')q=1,ch=getchar();
while(ch>='0'&&ch<='9')w=w*10+ch-'0',ch=getchar();
return q?-w:w;
}
struct Tarjan{
static const int N=500010,M=500010;
int n,m,be,tot,_clock,scc;
int ne[M],to[M];bool in[N];vector<int>p[N];
int bar[N],fr[N],low[N],dfn[N],f[N],st[N],s[N],ss[N];
void add(int u,int v){
to[++tot]=v;ne[tot]=fr[u];fr[u]=tot;
}
void Init(){
n=gi(),m=gi();
for(int i=1;i<=m;i++){
int u=gi(),v=gi();add(u,v);
}
for(int i=1;i<=n;i++)ss[i]=gi();
be=gi(),m=gi();
for(int i=1;i<=m;i++)bar[i]=gi();
}
inline void dfs(int x){
dfn[x]=low[x]=++_clock;
st[++tot]=x;in[x]=true;
for(int o=fr[x];o;o=ne[o])
if(!dfn[to[o]])dfs(to[o]),low[x]=min(low[x],low[to[o]]);
else if(in[to[o]])low[x]=min(low[x],low[to[o]]);
if(dfn[x]==low[x]){
scc++;
while(st[tot]!=x){
f[st[tot]]=scc;in[st[tot]]=false;tot--;
}
f[x]=scc;in[x]=false;tot--;
}
}
inline int src(int x){//let every node just go once
if(in[x])return f[x];in[x]=true;
int to=p[x].size();
for(int i=0;i<to;i++)
f[x]=max(f[x],src(p[x][i]));
if(f[x]||st[x])f[x]+=s[x];
return f[x];
}
void Work(){
_clock=tot=scc=0;
memset(dfn,0,sizeof(dfn));
memset(in,false,sizeof(in));
for(int i=1;i<=n;i++)
if(!dfn[i])dfs(i);
for(int i=1;i<=n;i++)s[f[i]]+=ss[i];
for(int i=1;i<=n;i++)
for(int o=fr[i];o;o=ne[o]){
if(f[i]==f[to[o]])continue;
p[f[i]].push_back(f[to[o]]);
}
memset(st,0,sizeof(st));memset(in,0,sizeof(0));
for(int i=1;i<=m;i++)bar[i]=f[bar[i]],st[bar[i]]=1;
be=f[be];memset(f,0,sizeof(f));
printf("%d",src(be));
}
}Tar;
int main()
{
freopen("atm.in","r",stdin);
freopen("atm.out","w",stdout);
Tar.Init();Tar.Work();
return 0;
}

【Apio2009】Bzoj1179 Atm的更多相关文章

  1. 【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm

    缩点后转化成 DAG图上的单源最长路问题.spfa/dp随便. #include<cstdio> #include<queue> #include<algorithm&g ...

  2. 【BZOJ】【1177】【APIO2009】Oil

    DP 找出三个正方形,可以转化为将整个油田切成三个矩形块,每块中各找一个正方形区域,切的形式只有6种,分类更新ans即可 题解:http://trinklee.blog.163.com/blog/st ...

  3. 【BZOJ】【1178】【APIO2009】convention会议中心

    贪心 如果不考虑字典序的话,直接按右端点排序,能选就选,就可以算出ans…… 但是要算一个字典序最小的解就比较蛋疼了= = Orz了zyf的题解 就是按字典序从小到大依次枚举,在不改变答案的情况下,能 ...

  4. 缩点+spfa最长路【bzoj】 1179: [Apio2009]Atm

    [bzoj] 1179: [Apio2009]Atm Description Siruseri 城中的道路都是单向的.不同的道路由路口连接.按照法律的规定, 在每个路口都设立了一个 Siruseri ...

  5. 【BZOJ4317】Atm的树 动态树分治+二分+线段树

    [BZOJ4317]Atm的树 Description Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径 ...

  6. 【题解】[APIO2009]会议中心

    [题解][P3626 APIO2009]会议中心 真的是一道好题!!!刷新了我对倍增浅显的认识. 此题若没有第二份输出一个字典序的方案,就是一道\(sort+\)贪心,但是第二问使得我们要用另外的办法 ...

  7. 【动态规划】HDU 5781 ATM Mechine

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5781 题目大意: 一个人有[0,K]内随机的钱,每次可以随意取,但是不知道什么时候取完,取钱超过剩余 ...

  8. 【tarjan+SPFA】BZOJ1179-[Apio2009]Atm

    [题目大意] 给出一张有点权的有向图,已知起点和可以作为终点的一些点,问由起点出发,每条边和每个点可以经过任意多次,经过点的权值总和最大为多少. [思路] 由于可以走任意多次,显然强连通分量可以缩点. ...

  9. 【NOI2014】起床困难综合症(贪心)

    [NOI2014]起床困难综合症(贪心) 题面 Description 21 世纪,许多人得了一种奇怪的病:起床困难综合症,其临床表现为:起床难,起床后精神不佳.作为一名青春阳光好少年,atm 一直坚 ...

随机推荐

  1. .net core 中简单封装Dapper.Extensions 并使用sqlsuger自动生成实体类

    引言 由公司需要使用dapper  同时支持多数据库 又需要支持实体类 又需要支持sql 还需要支持事务 所以采用了 dapper + dapperExtensions  并配套 生成实体类小工具的方 ...

  2. C++ map使用总结

    0. Backgroud 此文章源于博主(sunshinewave),转到自己博客以后方便查看 map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次, ...

  3. 洛谷——P1168 中位数

    P1168 中位数 题目描述 给出一个长度为NN的非负整数序列$A_i$​,对于所有1 ≤ k ≤ (N + 1),输出$A_1, A_3, …, A_{2k - 1}A1​,A3​,…,A2k−1​ ...

  4. UVA - 247 Calling Circles(Floyd求传递闭包)

    题目: 思路: 利用Floyd求传递闭包(mp[i][j] = mp[i][j]||(mp[i][k]&&mp[k][j]);),当mp[i][j]=1&&mp[j][ ...

  5. python求两个链表组成的数字的和

    给定两个非空链表来表示两个非负整数.位数按照逆序方式存储,它们的每个节点只存储单个数字.将两数相加返回一个新的链表. 你可以假设除了数字 0 之外,这两个数字都不会以零开头. 示例: 输入:(2 -& ...

  6. Linux有几种安装软件的方式?????

    看了Windows后台软件安装的过程,想必Linux也是这样.拿RHEL7来打比方 最开始Linux上安装软件只提供源代码,需要自己去编译源代码,拷贝库文件等 RPM 红帽软件包管理器可以自动地执行上 ...

  7. python re模块与正则

    1. re模块 1.1 转义符 正则表达式中的转义符在python的字符串中也刚好有转移的作用,但是正则表达式中的转义符和字符串中的转义符并没关系,且还容易有冲突. 为了避免这种冲突,我们所有的正则都 ...

  8. 原生js实现三个按钮绑定三个计时器,点击其中一个按钮,开启当前计时器,另外另个不开启

    今天在某个前端交流群,有个小伙伴问了一个小功能,自己想了一下,代码如下,可以实现基本功能: 下面是html结构 <div id="demo"> <input ty ...

  9. intel compiler的表现

    好久没弄这个东西,今天突然想试下,代码没写完,以后补. #include <stdio.h> #include <stdlib.h> #include <time.h&g ...

  10. PAT 1137 Final Grading

    For a student taking the online course "Data Structures" on China University MOOC (http:// ...