BZOJ 1179: [Apio2009]Atm tarjan + spfa
Code:
#include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define maxn 500009 #define ll long long using namespace std; map<int,int>M[maxn]; vector<int>G[maxn]; stack<int>S; int n,m,edges,s,P,a,scc,num; int viss[maxn]; int hd[maxn],to[maxn],nex[maxn],val[maxn],mk[maxn],dfn[maxn],low[maxn],idx[maxn],vis[maxn]; ll dp[maxn],total[maxn]; inline void add(int u,int v){ nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void tarjan(int u) { low[u]=dfn[u]=++scc, vis[u]=1; S.push(u); for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(!vis[v]) tarjan(v), low[u]=min(low[u], low[v]); else if(vis[v]==1) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { ++num; int po=0; for(;;) { int x=S.top(); S.pop(); po+=val[x],vis[x]=-1,idx[x]=num; if(x==u) break; } total[num]=po; } } queue<int>Q; inline void spfa() { Q.push(idx[s]); dp[idx[s]]=total[idx[s]], viss[idx[s]]=1; while(!Q.empty()) { int u=Q.front(); Q.pop(); viss[u]=0; for(int i=0;i<G[u].size();++i) { int v=G[u][i]; if(dp[u] + total[v] > dp[v]) { dp[v] = dp[u] + total[v]; if(!viss[v]) { Q.push(v); viss[v]=1; } } } } ll tr=0; for(int i=1;i<=n;++i) { if(mk[i]) { tr=max(tr, dp[idx[i]]); } } printf("%lld\n",tr); } int main() { // setIO("input"); scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) { int x,y; scanf("%d%d",&x,&y); if(x!=y) add(x,y); } for(int i=1;i<=n;++i) scanf("%d",&val[i]); scanf("%d%d",&s,&P); for(int i=1;i<=P;++i) scanf("%d",&a), mk[a]=1; tarjan(s); for(int i=1;i<=n;++i) { int cur=idx[i]; for(int j=hd[i];j;j=nex[j]) { int v=idx[to[j]]; if(!M[cur][v] && cur!=v) M[cur][v]=1, G[cur].push_back(v); } } spfa(); return 0; }