Description

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

Banditji 计划实施 Siruseri 有史以来最惊天动地的 ATM 抢劫。他将从市中心 出发,沿着单向道路行驶,抢劫所有他途径的 ATM 机,最终他将在一个酒吧庆 祝他的胜利。

使用高超的黑客技术,他获知了每个 ATM 机中可以掠取的现金数额。他希 望你帮助他计算从市中心出发最后到达某个酒吧时最多能抢劫的现金总数。他可 以经过同一路口或道路任意多次。但只要他抢劫过某个 ATM 机后,该 ATM 机 里面就不会再有钱了。 例如,假设该城中有 6 个路口,道路的连接情况如下图所示:

市中心在路口 1,由一个入口符号→来标识,那些有酒吧的路口用双圈来表

示。每个 ATM 机中可取的钱数标在了路口的上方。在这个例子中,Banditji 能抢 劫的现金总数为 47,实施的抢劫路线是:1-2-4-1-2-3-5。

Input

第一行包含两个整数 N、M。N 表示路口的个数,M 表示道路条数。接下来 M 行,每行两个整数,这两个整数都在 1 到 N 之间,第 i+1 行的两个整数表示第 i 条道路的起点和终点的路口编号。接下来 N 行,每行一个整数,按顺序表示每 个路口处的 ATM 机中的钱数。接下来一行包含两个整数 S、P,S 表示市中心的 编号,也就是出发的路口。P 表示酒吧数目。接下来的一行中有 P 个整数,表示 P 个有酒吧的路口的编号。

Output

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

\(Tarjan\)缩点跑最长路,

在求强联通分量的时候维护每个联通分量的\(val\)(即当前强联通分量中所有\(atm\)的钱数.

不能再次建边的时候再求.(会出锅,但是原理我不太知道。

再对强联通分量建边跑最长路即可.

注意:\(Dijkstra\)的贪心策略不可跑最长路。

这里数组可以重复使用,不过这题没有卡数组,就没有重复使用了 qwq.

代码

  1. #include<cstdio>
  2. #include<cctype>
  3. #include<queue>
  4. #define N 500008
  5. #define R register
  6. using namespace std;
  7. inline void in(int &x)
  8. {
  9. int f=1;x=0;char s=getchar();
  10. while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
  11. while(isdigit(s)){x=x*10+s-'0';s=getchar();}
  12. x*=f;
  13. }
  14. int n,m,head[N],tot,low[N],dfn[N],col,belong[N],idx,stk[N],pos;
  15. int val[N],v[N],h[N],ttt,p,t[N],dis[N],top,s,ans;
  16. struct cod{int u,v;}edge[N<<2],e[N<<2];
  17. bool inq[N],vis[N];
  18. inline void add(int x,int y)
  19. {
  20. edge[++tot].u=head[x];
  21. edge[tot].v=y;
  22. head[x]=tot;
  23. }
  24. inline void ado(int x,int y)
  25. {
  26. e[++ttt].u=h[x];
  27. e[ttt].v=y;
  28. h[x]=ttt;
  29. }
  30. inline void spfa(int s)
  31. {
  32. for(R int i=1;i<=col;i++)dis[i]=-214748364;
  33. queue<int>q;
  34. q.push(s);vis[s]=true;dis[s]=val[s];
  35. while(!q.empty())
  36. {
  37. int u=q.front();q.pop();vis[u]=false;
  38. for(R int i=h[u];i;i=e[i].u)
  39. {
  40. if(dis[e[i].v]<dis[u]+val[e[i].v])
  41. {
  42. dis[e[i].v]=dis[u]+val[e[i].v];
  43. if(!vis[e[i].v])
  44. {
  45. vis[e[i].v]=true;
  46. q.push(e[i].v);
  47. }
  48. }
  49. }
  50. }
  51. for(R int i=1;i<=p;i++)
  52. ans=max(ans,dis[belong[t[i]]]);
  53. printf("%d",ans);
  54. }
  55. void tarjan(int x)
  56. {
  57. dfn[x]=low[x]=++idx;
  58. stk[++top]=x;inq[x]=true;
  59. for(R int i=head[x];i;i=edge[i].u)
  60. {
  61. if(!dfn[edge[i].v])
  62. {
  63. tarjan(edge[i].v);
  64. low[x]=min(low[x],low[edge[i].v]);
  65. }
  66. else if(inq[edge[i].v])
  67. low[x]=min(low[x],dfn[edge[i].v]);
  68. }
  69. if(low[x]==dfn[x])
  70. {
  71. col++;
  72. int now=-1;
  73. while(now!=x)
  74. {
  75. now=stk[top--];
  76. inq[now]=false;
  77. belong[now]=col;
  78. val[col]+=v[now];
  79. }
  80. }
  81. }
  82. int main()
  83. {
  84. in(n),in(m);
  85. for(R int i=1,x,y;i<=m;i++)
  86. {
  87. in(x),in(y);
  88. add(x,y);
  89. }
  90. for(R int i=1;i<=n;i++)in(v[i]);
  91. for(R int i=1;i<=n;i++)
  92. if(!dfn[i])tarjan(i);
  93. for(R int i=1;i<=n;i++)
  94. for(R int j=head[i];j;j=edge[j].u)
  95. if(belong[edge[j].v]!=belong[i])
  96. ado(belong[i],belong[edge[j].v]);
  97. in(s);in(p);
  98. for(R int i=1;i<=p;i++)in(t[i]);
  99. spfa(belong[s]);
  100. }

Tarjan缩点+Spfa最长路【p3627】[APIO2009] 抢掠计划的更多相关文章

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

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

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

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

  3. P3627 [APIO2009]抢掠计划

    P3627 [APIO2009]抢掠计划 Tarjan缩点+最短(最长)路 显然的缩点...... 在缩点时,顺便维护每个强连通分量的总权值 缩完点按照惯例建个新图 然后跑一遍spfa最长路,枚举每个 ...

  4. 洛谷 P3627 [APIO2009]抢掠计划 Tarjan缩点+Spfa求最长路

    题目地址:https://www.luogu.com.cn/problem/P3627 第一次寒假训练的结测题,思路本身不难,但对于我这个码力蒟蒻来说实现难度不小-考试时肛了将近两个半小时才刚肛出来. ...

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

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

  6. Grouping ZOJ - 3795 (tarjan缩点求最长路)

    题目链接:https://cn.vjudge.net/problem/ZOJ-3795 题目大意:给你n个人,m个关系, 让你对这个n个人进行分组,要求:尽可能的分组最少,然后每个组里面的人都没有关系 ...

  7. BZOJ5450: 轰炸(水题,Tarjan缩点求最长路)

    5450: 轰炸 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 43  Solved:18[Submit][Status][Discuss] Desc ...

  8. BZOJ1093 [ZJOI2007]最大半连通子图 【tarjan缩点 + DAG最长路计数】

    题目 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意 两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G ...

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

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

随机推荐

  1. python学习笔记二:流程控制

    一.if else: #!/usr/bin/python x = int(raw_input('please input:')) if x >= 90: if x >= 95: print ...

  2. 【Kth Smallest Element in a BST 】cpp

    题目: Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. ...

  3. flask 基础ssti注入

    源代码地址 (请用python2.7运行,python3有点出入) 注入点: 不是返回的静态模板而是反回模板字符串变得让客户端可以控制. XSS 这里直接 http://39.105.116.195: ...

  4. Python字符串的常用操作学习

    >>> name = "I love my job!" >>> name.capitalize() #首字母大写 'I love my job! ...

  5. 孤荷凌寒自学python第十天序列之字符串的常用方法

    孤荷凌寒自学python第十天序列之字符串的常用方法 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) Python的字符串操作方法非常丰富,原生支持字符串的多种操作: 1 查找子字符串 str ...

  6. FTP数字代码的意义

    110 重新启动标记应答.120 服务在多久时间内ready.125 数据链路端口开启,准备传送.150 文件状态正常,开启数据连接端口.200 命令执行成功.202 命令执行失败.211 系统状态或 ...

  7. 原始套接字--icmp相关

    icmp请求 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <uni ...

  8. Qt编程的一些技巧

    1.Qt程序在运行过程中,调用函数(如lcdNumber->display(num))显示数据到界面上时,并不会马上刷新屏幕显示,而是要等主程序运行到函数a.exec()时,才刷新屏幕,如下 因 ...

  9. Nginx出现500错误解决办法

    查看错误日志D:\nginx\logs\error.log 得知:Nginx配置文件中会将路径中的 \t 默认转义成 空格 改为双斜杠就可以了

  10. RabbitMQ-Java客户端API指南-下

    RabbitMQ-Java客户端API指南-下 使用主机列表 可以将Address数组传递给newConnection().的地址是简单地在一个方便的类com.rabbitmq.client包与主机 ...