zoukankan      html  css  js  c++  java
  • bzoj1179: [Apio2009]Atm

    tatjan缩强连通分量,单源最长路。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 500000 + 10;
    const int maxm = 1000000 + 10;
    
    int G[maxn],V[maxm],Next[maxm],Eid;
    int g[maxn],v[maxm],next[maxm],eid;
    int n,m,S,T,p,cid,sp,vid,res;
    int q[maxm],l,r;
    int sum[maxn],color[maxn],W[maxn],w[maxn];
    int vis[maxn],dfn[maxn],low[maxn];
    int s[maxn];
    bool inque[maxn],bar[maxn],b[maxn];
    
    void Addedge(int a,int b) {
        V[Eid]=b; Next[Eid]=G[a]; G[a]=Eid++;
    }
    
    void addedge(int a,int b) {
        v[eid]=b; next[eid]=g[a]; g[a]=eid++;    
    }
    
    void build() {
        memset(G,-1,sizeof(G));
        scanf("%d%d",&n,&m);
        for(int i=1,a,b;i<=m;i++) {
            scanf("%d%d",&a,&b);
            Addedge(a,b);
        }
        for(int i=1;i<=n;i++) scanf("%d",&W[i]);
        scanf("%d%d",&T,&p);
        for(int i=1,a;i<=p;i++) {
            scanf("%d",&a);
            bar[a]=1;
        }
    }
    
    void tarjan(int u) {
        vis[u]=1;s[++sp]=u;
        dfn[u]=low[u]=++vid;
        
        for(int i=G[u];~i;i=Next[i]) {
            if(vis[V[i]]==0) {
                tarjan(V[i]);
                low[u]=min(low[u],low[V[i]]);    
            }
            else if(vis[V[i]]==1) {
                low[u]=min(low[u],dfn[V[i]]);
            }
        }
        
        if(dfn[u]==low[u]) {
            ++cid;
            do {
                int t=s[sp];
                color[t]=cid;
                w[cid]+=W[t];
                b[cid]|=bar[t];
                if(t==T) S=cid;
                vis[t]=2;
            } while(s[sp--]!=u);
        }
    }
    
    void predo() {
        for(int i=1;i<=n;i++) if(!vis[i]) tarjan(i);    
        memset(g,-1,sizeof(g));
        for(int u=1;u<=n;u++) 
        for(int i=G[u];~i;i=Next[i]) 
            if(color[u]!=color[V[i]])
                addedge(color[u],color[V[i]]);
    }
    
    void solve() {
        int u;
        l=r=0; q[r++]=S; sum[S]=w[S];
        while(l<r) {
            u=q[l++]; 
            inque[u]=0;
            if(b[u]) res=max(res,sum[u]);
            for(int i=g[u];~i;i=next[i]) 
                if(sum[v[i]]<sum[u]+w[v[i]]) {
                    sum[v[i]]=sum[u]+w[v[i]];    
                    if(!inque[v[i]]) 
                        inque[q[r++]=v[i]]=1;
                }
        }
        printf("%d
    ",res);
    }
    
    int main() {
        build();
        predo();
        solve();    
        return 0;
    }
  • 相关阅读:
    6大集合类
    数据导出到Excel/Word 防止出现乱码仅有一行数据导出的时候
    bootmgr is compressed 解决办法 汇总
    RAID 独立磁盘真阵列
    C# 和 Js 取出时间间隔
    Image 获取缩略图
    ConvertJSONDateToJSDateObject 方法实现json格式时间串转换为 对应的时间格式串
    纯js脚本的模式对话框
    癌症的IARC分级
    微信小程序如何在页面间传值
  • 原文地址:https://www.cnblogs.com/invoid/p/5498300.html
Copyright © 2011-2022 走看看