1. 程式人生 > >APIO2009 ATM

APIO2009 ATM

else hide family ide mage 一個 ++ tchar spa

技術分享
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
題目

技術分享

芒果君:縮點+SPFA最長路裸裸的啊,可是我把縮點前後搞混了QAQ

要點權轉邊權 然後就沒什麽好說的了……

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cmath>
  4 #include<algorithm>
  5 #include<vector>
  6 #include<map>
  7 #include<stack>
  8 #include<queue>
  9
#define inf 1<<29 10 #define maxn 500010 11 using namespace std; 12 typedef long long ll; 13 struct Edge{ 14 int v,ne; 15 }e[maxn],E[maxn]; 16 int cnt,tot,n,m,s,ans,jh[maxn],w[maxn],dis[maxn],dfn[maxn],low[maxn],hl[maxn],vis[maxn],HL[maxn],W[maxn]; 17 stack<int>S; 18 queue<int
>Q; 19 void add(int u,int v) 20 { 21 e[++cnt].v=v; 22 e[cnt].ne=hl[u]; 23 hl[u]=cnt; 24 } 25 ll read() 26 { 27 ll ret(0),f=1; 28 char ch=getchar(); 29 while(ch<0||ch>9){ 30 if(ch==-) f=-1; 31 ch=getchar(); 32 } 33 while(ch>=0&&ch<=9){ 34 ret=ret*10+ch-0; 35 ch=getchar(); 36 } 37 return ret*f; 38 } 39 void tarjan(int x) 40 { 41 S.push(x); 42 dfn[x]=low[x]=++cnt; 43 vis[x]=1; 44 for(int i=hl[x];i;i=e[i].ne){ 45 int v=e[i].v; 46 if(!dfn[v]){ 47 tarjan(v); 48 low[x]=min(low[x],low[v]); 49 } 50 else if(vis[v]) low[x]=min(low[x],dfn[v]); 51 } 52 if(dfn[x]==low[x]){ 53 tot++; 54 int now=-1; 55 while(now!=x){ 56 now=S.top(); 57 S.pop(); 58 jh[now]=tot; 59 vis[now]=0; 60 } 61 } 62 } 63 void rebuild() 64 { 65 for(int x=1;x<=n;++x){ 66 for(int i=hl[x];i;i=e[i].ne){ 67 int v=e[i].v; 68 if(jh[x]==jh[v]) continue; 69 E[++cnt].v=jh[v]; 70 E[cnt].ne=HL[jh[x]]; 71 HL[jh[x]]=cnt; 72 } 73 W[jh[x]]+=w[x]; 74 } 75 } 76 void spfa() 77 { 78 dis[jh[s]]=W[jh[s]]; 79 Q.push(jh[s]); 80 while(!Q.empty()){ 81 int x=Q.front(); 82 Q.pop(); 83 vis[x]=0; 84 for(int i=HL[x];i;i=E[i].ne){ 85 int v=E[i].v; 86 if(dis[x]+W[v]>dis[v]){ 87 dis[v]=dis[x]+W[v]; 88 if(!vis[v]){ 89 vis[v]=1; 90 Q.push(v); 91 } 92 } 93 } 94 } 95 } 96 int main() 97 { 98 int u,v; 99 n=read(),m=read(); 100 for(int i=1;i<=m;++i){ 101 u=read(),v=read(); 102 add(u,v); 103 } 104 for(int i=1;i<=n;++i) w[i]=read(); 105 s=read(),m=read(); 106 cnt=0; 107 for(int i=1;i<=n;++i) if(!dfn[i]) tarjan(i); 108 cnt=0; 109 rebuild(); 110 spfa(); 111 for(int i=1;i<=m;++i){ 112 v=read(); 113 ans=max(ans,dis[jh[v]]); 114 } 115 printf("%d",ans); 116 return 0; 117 }

APIO2009 ATM