[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的更多相关文章

  1. 强连通分量(tarjan求强连通分量)

    双DFS方法就是正dfs扫一遍,然后将边反向dfs扫一遍.<挑战程序设计>上有说明. 双dfs代码: #include <iostream> #include <cstd ...

  2. 有向图强连通分量 Tarjan算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  3. POJ2186 Popular Cows 强连通分量tarjan

    做这题主要是为了学习一下tarjan的强连通分量,因为包括桥,双连通分量,强连通分量很多的求法其实都可以源于tarjan的这种方法,通过一个low,pre数组求出来. 题意:给你许多的A->B ...

  4. [有向图的强连通分量][Tarjan算法]

    https://www.byvoid.com/blog/scc-tarjan 主要思想 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的 ...

  5. 图的连通性:有向图强连通分量-Tarjan算法

    参考资料:http://blog.csdn.net/lezg_bkbj/article/details/11538359 上面的资料,把强连通讲的很好很清楚,值得学习. 在一个有向图G中,若两顶点间至 ...

  6. 强连通分量tarjan缩点——POJ2186 Popular Cows

    这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定 ...

  7. 图之强连通、强连通图、强连通分量 Tarjan算法

    原文地址:https://blog.csdn.net/qq_16234613/article/details/77431043 一.解释 在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶 ...

  8. 图论-强连通分量-Tarjan算法

    有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...

  9. 求图的强连通分量--tarjan算法

    一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间 ...

随机推荐

  1. Python全栈工程师(元组、字典)

     ParisGabriel     感谢 大家的支持  你们的阅读评价就是我最好的更新动力  我会坚持吧排版做的越来越好        每天坚持 一天一篇 点个订阅吧  灰常感谢    当个死粉也阔以 ...

  2. neutron floating ip 限速

    查看浮动ip的id [root@10e131e69e14 oz]# openstack floating ip show 36.111.0.197 +---------------------+--- ...

  3. hnust 原石法阵

    问题 F: 原石法阵 时间限制: 1 Sec  内存限制: 128 MB提交: 1098  解决: 161[提交][状态][讨论版] 题目描述 WZH有一个由原石构成的n阶三角形魔法阵,三角形魔法阵如 ...

  4. __PRETTY_FUNCTION__,__func__,__FUNCTION__

    今天在看苹果的官方demo的时候,发现这个打印调用方法的参数,很是好奇,遂bing了一番. NSLog(@"----------------%s",__PRETTY_FUNCTIO ...

  5. [ARC083F] Collecting Balls [建二分图+环套树定向+建拓扑图+树的拓扑序计数]

    题面 [传送门](https://arc083.contest.atcoder.jp/tasks/arc083_d) 思路 这是一道真正的好题 第一步:转化模型 行列支配类的问题,常见做法就是把行和列 ...

  6. JZOJ 5280 膜法师

    好啰嗦......还好作者给了一句话题意,不然光看题就很耗费时间. 样例输入: 1 6 3 1 78 69 55 102 233 666 样例输出: 1 2 3 4 5 6 11  数据范围: 思路: ...

  7. 原来Java大数据才是真正的高富帅!

    大数据时代,中国IT环境也将面临重新洗牌,不仅仅是企业,更是程序员们转型可遇而不可求的机遇. 国内大多数大型互联网公司的程序员被称作研发工程师,但实际上国内几乎没有研发项目,只能叫做开发.开发程序员的 ...

  8. POJ2374 Fence Obstacle Course 【线段树】

    题目链接 POJ2374 题解 题意: 给出\(n\)个平行于\(x\)轴的栅栏,求从一侧栅栏的某个位置出发,绕过所有栅栏到达另一侧\(x = 0\)位置的最短水平距离 往上说都是线段树优化dp 我写 ...

  9. 乌班图 root权限获取

    点击左侧终端标 2 出现命令提示符 3 首先输入:sudo passwd root(设置root密码) 4 输入当前系统的账户密码(账户:admin-pc的密码) 5 输入新的root密码,确认新密码 ...

  10. 转 python数据类型详解

    python数据类型详解 目录 1.字符串 2.布尔类型 3.整数 4.浮点数 5.数字 6.列表 7.元组 8.字典 9.日期 1.字符串 1.1.如何在Python中使用字符串 a.使用单引号(' ...