[BZOJ1179][APIO2009][强连通分量Tarjan+spfa]ATM
[BZOJ1179][APIO2009]ATM
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的单向的道路到达其中的至少一个酒吧。
题目大意:在一个各个点都有权值有向图中,从一个点出发,走过的点权值清零。要求问如何走所得的总权值最大,并且可以在酒吧点结束。
题目分析:如果若干个点处在同一个强连通分量中,那么从这个强连通分量中任意一个节点出发必定能到达这个强连通分量中的任意一个点。所以可以把这些点用Tarjan缩成一个点,把强连通分量中的所有的点权加到那个缩成的点,然后把这些缩成的点重构图跑一遍spfa,输出到所有酒吧点的路中最长的即可。
下面贴AC代码:
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,cnt,re_cnt,S,P,CN,maxn,top,dfs_num;
int pre[],re_pre[],bar[],DFN[],LOW[],dye[],size[],tow[],vis[],w[],dist[];
struct pack{int to,next,d;} E[],re_E[];
void add_edge(int x,int y){
E[++cnt].to=y;
E[cnt].next=pre[x];
pre[x]=cnt;
}
void rebuild(){
for(int i=;i<=n;++i)
for(int j=pre[i];j;j=E[j].next)
if(dye[i]!=dye[E[j].to]&&dye[i]&&dye[E[j].to]){
re_E[++re_cnt].to=dye[E[j].to];
re_E[re_cnt].next=re_pre[dye[i]];
re_E[re_cnt].d=size[dye[E[j].to]];
re_pre[dye[i]]=re_cnt;
}
}
void tarjan(int pos){
vis[tow[++top]=pos]=;
DFN[pos]=LOW[pos]=++dfs_num;
for(int i=pre[pos];i;i=E[i].next){
if(!DFN[E[i].to]){
tarjan(E[i].to);
LOW[pos]=min(LOW[pos],LOW[E[i].to]);
}
else if(vis[E[i].to])
LOW[pos]=min(LOW[pos],DFN[E[i].to]);
}
if(DFN[pos]==LOW[pos]){
vis[pos]=;
size[dye[pos]=++CN]+=w[pos];
while(pos!=tow[top]){
size[dye[tow[top]]=CN]+=w[tow[top]];
vis[tow[top--]]=;
}
--top;
}
}
int spfa(int pos){
vis[pos]=;
for(int i=re_pre[pos];i;i=re_E[i].next){
int v=re_E[i].to; int k=re_E[i].d;
if(dist[pos]+k>dist[v]){
dist[v]=dist[pos]+k;
if(!vis[v]){
if(spfa(re_E[i].to)) return ;
}
else return ;
}
}
vis[pos]=;
return ;
}
int main(){
scanf("%d%d",&n,&m);
if(!n||!m) {printf("");return ;}
for(int i=;i<=m;++i){
int a,b;
scanf("%d%d",&a,&b);
add_edge(a,b);
}
for(int i=;i<=n;++i)
scanf("%d",&w[i]);
scanf("%d%d",&S,&P);
for(int i=;i<=P;++i){
int t;
scanf("%d",&t);
bar[t]=;
}
for(int i=;i<=n;++i)
if(!dye[i])
tarjan(i);
rebuild();
dist[dye[S]]=size[dye[S]];
spfa(dye[S]);
for(int i=;i<=n;++i)
if(bar[i])
if(dist[dye[i]]>maxn)
maxn=dist[dye[i]];
printf("%d",maxn);
return ;
}
[BZOJ1179][APIO2009][强连通分量Tarjan+spfa]ATM的更多相关文章
- 强连通分量(tarjan求强连通分量)
双DFS方法就是正dfs扫一遍,然后将边反向dfs扫一遍.<挑战程序设计>上有说明. 双dfs代码: #include <iostream> #include <cstd ...
- 有向图强连通分量 Tarjan算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- POJ2186 Popular Cows 强连通分量tarjan
做这题主要是为了学习一下tarjan的强连通分量,因为包括桥,双连通分量,强连通分量很多的求法其实都可以源于tarjan的这种方法,通过一个low,pre数组求出来. 题意:给你许多的A->B ...
- [有向图的强连通分量][Tarjan算法]
https://www.byvoid.com/blog/scc-tarjan 主要思想 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的 ...
- 图的连通性:有向图强连通分量-Tarjan算法
参考资料:http://blog.csdn.net/lezg_bkbj/article/details/11538359 上面的资料,把强连通讲的很好很清楚,值得学习. 在一个有向图G中,若两顶点间至 ...
- 强连通分量tarjan缩点——POJ2186 Popular Cows
这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定 ...
- 图之强连通、强连通图、强连通分量 Tarjan算法
原文地址:https://blog.csdn.net/qq_16234613/article/details/77431043 一.解释 在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶 ...
- 图论-强连通分量-Tarjan算法
有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...
- 求图的强连通分量--tarjan算法
一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间 ...
随机推荐
- Android开发实例总结
写一个修改密码的界面 1画界面总结: 需要弄清楚什么地方用相对布局,什么地方使用线性布局 希望这过后自己花时间去弄清楚他们内嵌的的所有组件以及组件的属性包括用法. 2逻辑总结: 逻辑描述总是那么几步的 ...
- JavaScript里面之dom操作
1.dom之选择元素 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 转载:Android SQLite数据库版本升级原理解析
Android使用SQLite数据库保存数据,那数据库版本升级是怎么回事呢,这里说一下. 一.软件v1.0 安装v1.0,假设v1.0版本只有一个account表,这时走继承SQLiteOpenHel ...
- python基础--用python执行系统命令
from os import system print(system('ping www.baidu.com'))
- 【bzoj3829】[Poi2014]FarmCraft 贪心
原文地址:http://www.cnblogs.com/GXZlegend/p/6826667.html 题目描述 In a village called Byteville, there are ...
- [hdu6437]Problem L. Videos
题目大意:有$n$个小时,有$m$个节目(每种节目都有类型$0/1$),有$k$个人,一个人连续看相同类型的节目会扣$w$快乐值. 每一种节目有都一个播放区间$[l,r]$.每个人同一时间只能看一个节 ...
- Recompile Squid with SSL Bump
https://docs.diladele.com/administrator_guide_4_0/system_configuration/https_filtering/recompile_squ ...
- vue的过渡效果
https://segmentfault.com/a/1190000007738518
- Command Pattern的简单介绍
Command pattern 的角色有:Command(抽象命令).ConcreteCommand(具体命令) .Invoker(传达命令者) .receiver(接收命令者)Client(客户类, ...
- python 下划线转驼峰
# 下划线转驼峰 def str2Hump(text): arr = filter(None, text.lower().split('_')) res = '' j = 0 for i in arr ...