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;   
}

  

posted @ 2019-07-15 09:41  EM-LGH  阅读(128)  评论(0编辑  收藏  举报