题目传送门

Description

Siruseri 城中的道路都是单向的。不同的道路由路口连接。按照法律的规定, 在每个路口都设立了一个 Siruser
i 银行的 ATM 取款机。令人奇怪的是,Siruseri 的酒吧也都设在路口,虽然并不是每个路口都设有酒吧。Bandit
ji 计划实施 Siruseri 有史以来最惊天动地的 ATM 抢劫。他将从市中心 出发,沿着单向道路行驶,抢劫所有他
途径的 ATM 机,最终他将在一个酒吧庆 祝他的胜利。使用高超的黑客技术,他获知了每个 ATM 机中可以掠取的
现金数额。他希 望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可 以经过同一路口
或道路任意多次。但只要他抢劫过某个 ATM 机后,该 ATM 机 里面就不会再有钱了。 例如,假设该城中有 6 个
路口,道路的连接情况如下图所示:
市中心在路口 1,由一个入口符号→来标识,那些有酒吧的路口用双圈来表示。每个 ATM 机中可取的钱数标在了
路口的上方。在这个例子中,Banditji 能抢 劫的现金总数为 47,实施的抢劫路线是:1-2-4-1-2-3-5。
输出一个整数,表示Banditji从市中心开始到某个酒吧结束所能抢劫的最多的现金总数。
 

Sol

感觉这题思路还是很明了的...先进行一遍tarjan求出图中所有的强连通分量,将他们缩点,然后在这个DAG中跑一遍spfa求最长路。

坑点:好像不能用dijkstra+heap求最长路&&主程序中调用tarjan不能仅一次。

 #include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<cstring>
#define maxn 500090 using namespace std;
typedef long long ll; int n,m,tot,sp,P,dfs_clock,scc_cnt;
int head[maxn],Head[maxn],val[maxn],dfn[maxn],low[maxn],scc[maxn],pub[maxn];
bool vis[maxn];
ll ans,scc_val[maxn],dis[maxn];
struct node{
int to,next;
}edge[maxn],Edge[maxn];
stack<int>st; void add(int x,int y)
{
edge[++tot].to=y;
edge[tot].next=head[x];
head[x]=tot;
} void ADD(int x,int y)
{
Edge[++tot].to=y;
Edge[tot].next=Head[x];
Head[x]=tot;
} void tarjan(int u)
{
dfn[u]=low[u]=++dfs_clock;
st.push(u);
for(int i=head[u];i;i=edge[i].next)
{
int v=edge[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(!scc[v]) low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
scc_cnt++;
while()
{
int x=st.top();st.pop();
scc[x]=scc_cnt;
scc_val[scc_cnt]+=val[x];
if(x==u) break;
}
}
} void dijkstra(int s)
{
priority_queue<pair<ll,int> >q;
for(int i=;i<=scc_cnt;i++) dis[i]=-;
q.push(make_pair(,s));dis[s]=scc_val[s];
while(!q.empty())
{
int u=q.top().second;q.pop();
if(vis[u]) continue;
vis[u]=;
for(int i=Head[u];i;i=Edge[i].next)
{
int v=Edge[i].to;
if(dis[v]<dis[u]+scc_val[v])
{
dis[v]=dis[u]+scc_val[v];
q.push(make_pair(dis[v],v));
}
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
{
int x=,y=;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=;i<=n;i++) scanf("%d",&val[i]);
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
tot=;
for(int x=;x<=n;x++)
for(int i=head[x];i;i=edge[i].next)
{
int y=edge[i].to;
if(scc[x]!=scc[y])
ADD(scc[x],scc[y]);
}
scanf("%d%d",&sp,&P);
for(int i=;i<=P;i++) scanf("%d",&pub[i]);
dijkstra(scc[sp]);
for(int i=;i<=P;i++)
ans=max(ans,dis[scc[pub[i]]]);
printf("%lld\n",ans);
return ;
}

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

  1. BZOJ1179 : [Apio2009]Atm 缩点+spfa

    1179: [Apio2009]Atm Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 2069  Solved: 826[Submit][Status ...

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

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

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

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

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

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

  5. bzoj1179 [Apio2009]Atm——缩环最长路

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1179 tarjan 缩环,然后求到有酒吧的点的最长路即可: 但一开始想缩环后用拓扑序求答案, ...

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

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

  7. [BZOJ1179][APIO2009][强连通分量Tarjan+spfa]ATM

    [BZOJ1179][APIO2009]ATM Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i ...

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

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

  9. UVA11324 The Largest Clique (强连通缩点+DP最长路)

    <题目链接> 题目大意: 给你一张有向图 G,求一个结点数最大的结点集,使得该结点集中的任意两个结点 u 和 v 满足:要么 u 可以达 v,要么 v 可以达 u(u,v相互可达也行). ...

随机推荐

  1. dubbo springCloud比较

    1.dubbo只是专注于服务之间的治理,配置中心.分布式跟踪等这些内容都需要自己集成 2.dubbo核心功能: a.远程通讯 b.集群容错 c.自动发现 Dubbo SpringCloud 服务注册中 ...

  2. java设计模式----复合模式

    复合模式:复合模式结合两个或以上的模式,组成一个解决方案,解决一再发生的一般性问题 要点: 1.MVC是复合模式,结合了观察者模式.策略模式和组合模式 2.模型使用观察者模式,以便观察者更新,同时保持 ...

  3. LeetCode(66)题解: Plus One

    https://leetcode.com/problems/plus-one/ 题目: Given a non-negative number represented as an array of d ...

  4. CSS3 的10种Loading

    昨晚用CSS3实现了几种常见的Loading效果,虽然很简单,但还是分享一下,顺便也当是做做笔记…… 第1种效果: 代码如下: <div class="loading"> ...

  5. Mac开发必备工具(二)—— iTerm 2

    iTerm 2 简介 iTerm 2 is a terminal emulator for Mac OS X that does amazing things. iTerm 2 有很多能够提升效率的实 ...

  6. proc_create的使用方法

    proc_create的使用方法 proc文件系统是个有用的东东.创建一个proc虚拟文件,应用层通过读写该文件,即可实现与内核的交互.proc虚拟文件是如何创建的呢? 先看看比较简单的,创建proc ...

  7. IO、FileInputStream、(二十)

    1.IO流概述及其分类 * 1.概念(什么是IO?) * IO流用来处理设备之间的数据传输 * Java对数据的操作是通过流的方式 * Java用于操作流的类都在IO包中 * 流按流向分为两种:输入流 ...

  8. js操作创建和操作外部样式的例子

    兼容IE8及以上的IE浏览器1. [代码][HTML]代码 <!DOCTYPE html><html lang="en">    <head>  ...

  9. VM 下安装ghost版系统

    一.首先分区,并激活主分区 二.设置cd-rom的接口为IDE(这项看情况来设置,如果提示 "units specified don't exist, SHSUCDX can't insta ...

  10. PDB文件说明

    文/玄魂 .PDB文件,全称为“程序数据库”文件.我们使用它(更确切的说是看到它被应用)大多数场景是调试应用程序.目前我们对.PDB文件的普遍认知是它存储了被编译文件的调试信息,作为符号文件存在.那么 ...