【luogu3627】 [APIO2009]抢掠计划 [tarjan 缩点][最短路]

P3627 [APIO2009]抢掠计划

看到可以走多次 考虑缩点

缩点后重新建一个图跑一边spfa 速度感人

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=500000+5,inf=0x3f3f3f3f;
int n,m,w[N],S,p,ans=0;
int idx=0,Bcnt=0,dfn[N],low[N],bl[N],sum[N];
stack<int>s;
bool inst[N];
template<class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

int head[N],tot=0;
struct edge{int u,v,nxt;}e[N];
void add(int u,int v){
    e[++tot]=(edge){u,v,head[u]};head[u]=tot;
}

void tarjan(int u){
    dfn[u]=low[u]=++idx;
    s.push(u),inst[u]=1;
    for(int i=head[u],v;i;i=e[i].nxt){
        v=e[i].v;
        if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]);
        else if(inst[v]&&dfn[v]<low[u]) low[u]=dfn[v];
    }
    if(dfn[u]==low[u]){
        ++Bcnt;
        int v;
        do{
            v=s.top(),s.pop();
            bl[v]=Bcnt,sum[Bcnt]+=w[v],inst[v]=0;
        }while(u!=v);
    }
}

int head2[N],tot2=0;
struct edge2{int v,nxt,w;}e2[N];
void add2(int u,int v,int w){
    e2[++tot2]=(edge2){v,head2[u],w};head2[u]=tot2;
}

int dis[N];bool vis[N];
queue<int>q;
void spfa(){
    memset(dis,0,sizeof(dis));
    q.push(bl[S]);
    dis[bl[S]]=sum[bl[S]],vis[S]=1;
    while(!q.empty()){
        int u=q.front();
        q.pop(),vis[u]=0;
        for(int i=head2[u],v,w;i;i=e2[i].nxt){
            v=e2[i].v,w=e2[i].w;
            if(dis[v]<dis[u]+w){
                dis[v]=dis[u]+w;
                if(vis[v]==0) q.push(v),vis[v]=1;
            }
        }
    }
}

int main(){
    freopen("in.txt","r",stdin);
    rd(n),rd(m);
    for(int i=1,u,v;i<=m;++i) rd(u),rd(v),add(u,v);
    for(int i=1;i<=n;++i) rd(w[i]);
    memset(dfn,0,sizeof(dfn));
    for(int i=1;i<=n;++i)
    if(!dfn[i]) tarjan(i);
    for(int i=1;i<=tot;++i)
    if(bl[e[i].u]!=bl[e[i].v]) add2(bl[e[i].u],bl[e[i].v],sum[bl[e[i].v]]);
    rd(S),rd(p);
    spfa();
    for(int i=1,x;i<=p;++i){
        rd(x);
        ans=max(ans,dis[bl[x]]);
    }
    printf("%d",ans);
    return 0;
}

 

posted @ 2019-07-09 15:34  委屈的咸鱼鱼鱼鱼  阅读(160)  评论(0编辑  收藏  举报