博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[APIO2009]抢掠计划
阅读量:5284 次
发布时间:2019-06-14

本文共 3235 字,大约阅读时间需要 10 分钟。

题目描述

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

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

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

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

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

输入输出格式

输入格式:

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

输出格式:

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

输入输出样例

输入样例#1:
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
输出样例#1:
47

说明

50%的输入保证 N, M<=3000。所有的输入保证 N, M<=500000。每个 ATM 机中可取的钱数为一个非负整数且不超过 4000。

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

 

把一个强连通分量缩成一个点,判断每个点内有没有酒吧,搞两个dfs就好了。

代码:

1 #include
2 #include
3 #include
4 #define M 600010 5 using namespace std; 6 struct point{ 7 int next,to; 8 }e[M]; 9 int n,m,num,top,cnt,tot,P,S;10 int dfn[M],low[M],co[M],st[M],head[M];11 int sum[M],f[M],val[M],a[M],b[M];12 bool vis[M],bar[M],can[M];13 void add(int from,int to)14 {15 e[++num].next=head[from];16 e[num].to=to;17 head[from]=num;18 }19 void tarjan(int x)20 {21 dfn[x]=low[x]=++cnt;22 st[++top]=x;23 vis[x]=true;24 for(int i=head[x];i;i=e[i].next)25 {26 int to=e[i].to;27 if(!dfn[to])28 {29 tarjan(to);30 low[x]=min(low[x],low[to]);31 }32 else if(vis[to]) low[x]=min(low[x],dfn[to]);33 }34 if(dfn[x]==low[x])35 {36 tot++;37 while(st[top+1]!=x)38 {39 co[st[top]]=tot;40 vis[st[top]]=false;41 sum[tot]+=val[st[top]];42 if(bar[st[top]]) can[tot]=true;43 top--;44 }45 }46 }47 void check(int x)48 {49 vis[x]=true;50 for(int i=head[x];i;i=e[i].next)51 {52 int to=e[i].to;53 if(!vis[to]) check(to);54 if(can[to]) can[x]=true;55 }56 }57 void dfs(int x)58 {59 f[x]=sum[x];60 int maxn=0;61 for(int i=head[x];i;i=e[i].next)62 {63 int to=e[i].to;64 if(!can[to]) continue;65 if(!f[to]) dfs(to);66 maxn=max(maxn,f[to]);67 }68 f[x]+=maxn;69 }70 int main()71 {72 scanf("%d%d",&n,&m);73 for(int i=1;i<=m;i++)74 {75 scanf("%d%d",&a[i],&b[i]);76 add(a[i],b[i]);77 }78 for(int i=1;i<=n;i++) scanf("%d",&val[i]);79 scanf("%d%d",&S,&P);80 for(int i=1;i<=P;i++)81 {82 int x;scanf("%d",&x);83 bar[x]=true;84 }85 tarjan(S);86 num=0;87 memset(e,0,sizeof(e));88 memset(head,0,sizeof(head));89 memset(vis,false,sizeof(vis));90 for(int i=1;i<=m;i++)91 if(co[a[i]]!=co[b[i]]&&co[a[i]]&&co[b[i]])92 add(co[a[i]],co[b[i]]);93 check(co[S]);94 dfs(co[S]);95 printf("%d",f[co[S]]);96 return 0;97 }

 

转载于:https://www.cnblogs.com/Slrslr/p/9502784.html

你可能感兴趣的文章
垂直居中及水平垂直居中方案(共15种)
查看>>
JavaScript高级程序设计26.pdf
查看>>
jquery 对 table 的操作
查看>>
centos7 关闭防火墙
查看>>
Android 拍照图片选取与图片剪裁
查看>>
百度地图轨迹回放,自定义路书,边走边画线
查看>>
04-jQuery的属性操作
查看>>
PHP中---范围解析操作符(::)
查看>>
response实现文件下载
查看>>
【WP7】页面之间数据交互
查看>>
C++中的unique函数
查看>>
小白学数据分析----->流失分析设计
查看>>
FontAwesome 奥森图标的学习
查看>>
request response cookie session
查看>>
spring
查看>>
开源cms
查看>>
指针与引用
查看>>
THREADSPOOL
查看>>
jira集成fisheye代码深度查看工具安装绿色版
查看>>
C#跨线程操作控件的最简单实现探究
查看>>