首页 > 代码库 > bzoj1179: [Apio2009]Atm
bzoj1179: [Apio2009]Atm
tarjan缩点就是DAG上求最长路把。。。然而我并不会求。。。只会写spfa了。。。
#include<cstdio>#include<cstring>#include<cctype>#include<algorithm>#include<stack>#include<queue>using namespace std;#define rep(i,s,t) for(int i=s;i<=t;i++)#define dwn(i,s,t) for(int i=s;i>=t;i--)#define clr(x,c) memset(x,c,sizeof(x))#define qwq(x) for(edge *o=head[x];o;o=o->next)#define qaq(x) for(edge *o=h[x];o;o=o->next)int read(){ int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-‘0‘,c=getchar(); return x;} const int nmax=500005;const int inf=0x7f7f7f7f;struct edge{ int to;edge *next;};edge es[nmax<<1],*pt=es,*head[nmax],*h[nmax];void add(int u,int v){ pt->to=v;pt->next=head[u];head[u]=pt++;}int pre[nmax],a[nmax],scc[nmax],dfs_clock,scc_cnt;stack<int>s;int dfs(int x){ int lowu=pre[x]=++dfs_clock;s.push(x); qwq(x){ if(!pre[o->to]) lowu=min(lowu,dfs(o->to)); else if(!scc[o->to]) lowu=min(lowu,pre[o->to]); } if(lowu==pre[x]){ int o;scc_cnt++; while(1){ o=s.top();s.pop();scc[o]=scc_cnt; if(o==x) break; } } return lowu;}void adde(int u,int v){ pt->to=v;pt->next=h[u];h[u]=pt++;}int dist[nmax];bool inq[nmax];queue<int>q;void spfa(int s){ q.push(s);inq[s]=1;dist[s]=a[s]; int tx,td; while(!q.empty()){ tx=q.front();q.pop();inq[tx]=0; qaq(tx) if(dist[o->to]<dist[tx]+a[o->to]){ dist[o->to]=dist[tx]+a[o->to]; if(!inq[o->to]) q.push(o->to),inq[o->to]=1; } }}int main(){ int n=read(),m=read(),u,v; rep(i,1,m) u=read(),v=read(),add(u,v); rep(i,1,n) if(!pre[i]) dfs(i); rep(i,1,n) u=read(),a[scc[i]]+=u; rep(i,1,n) { qwq(i) { u=scc[i],v=scc[o->to]; if(u!=v) adde(u,v); } } int s=read(),tm=read(),ans=0; spfa(scc[s]); rep(i,1,tm) u=read(),ans=max(ans,dist[scc[u]]); printf("%d\n",ans); return 0;}
1179: [Apio2009]Atm
Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 2754 Solved: 1143
[Submit][Status][Discuss]
Description
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
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的单向的道路到达其中的至少一个酒吧。
Source
bzoj1179: [Apio2009]Atm
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。