• 【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;
    }
  • 相关阅读:
    Mysql关键字冲突的解决方案
    js日期时间函数
    Mysql字符串字段中是否包含某个字符串,用 find_in_set
    mysql中 where in 用法
    Best of Best系列(4)——AAAI
    Best of Best系列(5)——IJCAI
    Best of Best系列(3)——ICML
    Best of Best系列(6)——SIGIR
    Best of Best系列(2)——ICCV
    Best of Best系列(1)——CVPR
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11157738.html
Copyright © 2020-2023  润新知