APIO2009 ATM
阿新 • • 發佈:2017-10-30
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