【bzoj】 1179: [Apio2009]Atm

Description

Siruseri 城中的道路都是单向的。不同的道路由路口连接。按照法律的规定, 在每个路口都设立了一个 Siruseri 银行的 ATM 取款机。令人奇怪的是,Siruseri 的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。Banditji 计划实施 Siruseri 有史以来最惊天动地的 ATM 抢劫。他将从市中心 出发,沿着单向道路行驶,抢劫所有他

途径的 ATM 机,最终他将在一个酒吧庆 祝他的胜利。使用高超的黑客技术,他获知了每个 ATM 机中可以掠取的现金数额。他希 望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可 以经过同一路口或道路任意多次。但只要他抢劫过某个 ATM 机后,该 ATM 机 里面就不会再有钱了。

Input

第一行包含两个整数N、M。N表示路口的个数,M表示道路条数。

接下来M行,每行两个整数,这两个整数都在1到N之间,

第i+1行的两个整数表示第i条道路的起点和终点的路口编号。

接下来N行,每行一个整数,按顺序表示每个路口处的ATM机中的钱数。

接下来一行包含两个整数S、P,S表示市中心的编号,也就是出发的路口。P表示酒吧数目。

接下来的一行中有P个整数,表示P个有酒吧的路口的编号

N, M<=500000。每个ATM机中可取的钱数为一个非负整数且不超过4000。

输入数据保证你可以从市中心沿着Siruseri的单向的道路到达其中的至少一个酒吧。

Output

输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。

莫名其妙的自信自己可以一遍A,毕竟做过几乎一样的加强版(捂脸。。。)

先缩点,把强连通分量里的每一个点的权值全部赋给所之后的点,也就是belong[i]。

再对于缩完点之后的图,跑一个点权SPFA就可以了。

拓扑排序+DP的做法会更快,不过有待学习。

code:

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int wx=500017;
inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=(sum<<1)+(sum<<3)+ch-'0';ch=getchar();}
return sum*f;
}
struct e{
int nxt,to,dis;
}edge[wx];
struct E{
int nxt,to;
}Edge[wx];
int n,m;
int num,Tot,top,tot,col;
int a[wx],A[wx],belong[wx],size[wx],dis[wx],vis[wx];
int head[wx],Head[wx],dfn[wx],low[wx],st[wx],flag[wx];
void add(int from,int to,int dis){
edge[++num].nxt=head[from];
edge[num].to=to;
edge[num].dis=dis;
head[from]=num;
}
void add(int from,int to){
Edge[++Tot].nxt=Head[from];
Edge[Tot].to=to;
Head[from]=Tot;
}
void Tarjan(int u){
dfn[u]=low[u]=++tot;
st[++top]=u;
for(int i=Head[u];i;i=Edge[i].nxt){
int v=Edge[i].to;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!belong[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
belong[u]=++col;
size[col]++;
A[col]+=a[u];
while(st[top]!=u){
belong[st[top]]=col;
size[col]++;
A[col]+=a[st[top]];
top--;
}
top--;
}
}
void CQ(){
for(int u=1;u<=n;u++){
for(int i=Head[u];i;i=Edge[i].nxt){
int v=Edge[i].to;
if(belong[u]!=belong[v]){
add(belong[u],belong[v],0);
}
}
}
}
queue<int > q;
void SPFA(int s){
for(int i=1;i<=col;i++)dis[i]=-1;
dis[s]=A[s];vis[s]=1;q.push(s);
while(q.size()){
int u=q.front();q.pop();
vis[u]=0;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(dis[v]<dis[u]+A[v]){
dis[v]=dis[u]+A[v];
if(!vis[v]){
vis[v]=1;q.push(v);
}
}
}
}
}
int main(){
n=read();m=read();
for(int i=1,x,y;i<=m;i++){
x=read();y=read();add(x,y);
}
for(int i=1;i<=n;i++)a[i]=read();
int s,p;s=read();p=read();
for(int i=1,x;i<=p;i++){
x=read();flag[i]=x;
}
for(int i=1;i<=n;i++){
if(!dfn[i])Tarjan(i);
}
CQ();
SPFA(belong[s]);
int ans=0;
for(int i=1;i<=p;i++){
ans=max(ans,dis[belong[flag[i]]]);
}
printf("%d\n",ans);
return 0;
}

缩点+spfa最长路【bzoj】 1179: [Apio2009]Atm的更多相关文章

  1. 【bzoj1179】[Apio2009]Atm Tarjan缩点+Spfa最长路

    题目描述 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每 ...

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

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

  3. bzoj 1179: [Apio2009]Atm【tarjan+spfa】

    明明优化了spfa还是好慢-- 因为只能取一次值,所以先tarjan缩点,把一个scc的点权和加起来作为新点的点权,然后建立新图.在新图上跑spfa最长路,最后把酒吧点的dis取个max就是答案. # ...

  4. BZOJ 1179 [Apio2009]Atm(强连通分量)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1179 [题目大意] 给出一张有向带环点权图,给出一些终点,在路径中同一个点的点权只能累 ...

  5. BZOJ 1179: [Apio2009]Atm( tarjan + 最短路 )

    对于一个强连通分量, 一定是整个走或者不走, 所以tarjan缩点然后跑dijkstra. ------------------------------------------------------ ...

  6. bzoj 1179 [Apio2009]Atm——SCC缩点+spfa

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1179 显然SCC缩点. 然后准备倒着拓扑序推到st,结果WA. 听TJ说dj求最长路会发生不 ...

  7. bzoj1179: [Apio2009]Atm 【缩点+spfa最长路】

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

  8. [luogu3627 APIO2009] 抢掠计划 (tarjan缩点+spfa最长路)

    传送门 Description Input 第一行包含两个整数 N.M.N 表示路口的个数,M 表示道路条数.接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表 ...

  9. bzoj 1179[Apio2009]Atm (tarjan+spfa)

    题目 输入 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口编号.接下来N行,每行一 ...

随机推荐

  1. 如何通过ISO安装win7程序

    从下载u启动工具到安装Ghost Win7系统教程 来源:http://www.uqidong.com时间:2013-08-12 09:17:38 怎样用u启动u盘启动盘安装ghost系统?u启动制作 ...

  2. Python Django框架 补充

    Django REST framework ORM框架整理 Django框架 app间互借models字段的操作 ORM数据库操作补充:models中的一对一操作.过滤.事务 Django model ...

  3. vue实用难点讲解

    此篇文章是我基于研究vue文档三遍的基础上,觉得还有点难理解或者难记的知识点总结 列表渲染 1.渲染组件必须加key,并且属性是手动传递给组件的 <my-component v-for=&quo ...

  4. 管理linked break-off snapshot

    1. 建立linked break-off snapshot   (1) 建立原卷 #> vxassist -g APS2_AFC_DG make vol1 4096000 #> vxpr ...

  5. 部署和调优 2.5 tomcat配置和优化

    配置文件 vim /usr/local/tomcat/conf/server.xml 修改 <Connector port=" protocol="HTTP/1.1" ...

  6. 信号量sem 的用法

    #include <semaphore.h> sem_t sem; sem_init(&sem, 0, 0); sem_post(&sem); sem_wait(& ...

  7. strophe与openfire模拟的XMPP简单hello程序

    /* * 参考<XMPP高级编程+使用JavaScript和jQuery>第三章例子. * 我修改了作者的XMPP服务器到本地的openfire.JavaScript跨域请求,使用Ngin ...

  8. 前端JS面试题

    题目如下: function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function ( ...

  9. css代码结构

    整个文档结构如下: 一般性样式 主体样式 reset样式 链接 标题 其他元素 辅助样式 表单 通知和错误 一致的条目 页面结构 标题.页脚和导航 布局 其他页面结构元素 页面组件 各个页面 覆盖

  10. Solr搜索的排序打分规则探讨

    使用Solr搭建搜索引擎很容易,但是如何制定合理的打分规则(boost)做排序却是一个很头痛的事情.Solr本身的排序打分规则是继承自Lucene的文本相关度的打分即boost,这一套算法对于通用的提 ...