zoukankan      html  css  js  c++  java
  • luogu P3387 【模板】缩点

    还是很好些的.

    Code:

    #include <stack>
    #include <cstdio>
    #include <algorithm>
    #include <queue> 
    #include <cstring>
    #include <map> 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;
    namespace Tarjan{
        #define maxn 1000000 
        #define ll long long 
        map<int,int>ed[maxn]; 
        int scc,sig; 
        int vis[maxn]; 
        int du[maxn]; 
        int idx[maxn];   
        int pre[maxn],low[maxn]; 
        int val[maxn];       
        long long value[maxn];  
        long long ans[maxn]; 
        stack<int>S; 
        queue<int>Q; 
        struct graph{
            int cnt; 
            int head[maxn],to[maxn<<1],nex[maxn<<1];  
            void addedge(int u,int v){
                nex[++cnt] = head[u],head[u]=cnt,to[cnt] = v; 
            }
        }G1,G2; 
        void tarjan(int u){
            S.push(u); 
            vis[u] = 1;         
            pre[u] = low[u] = ++scc; 
            for(int v=G1.head[u];v;v=G1.nex[v]){
                if(!vis[G1.to[v]]) {
                    tarjan(G1.to[v]); 
                    low[u] = min(low[u],low[G1.to[v]]); 
                }
                else if(vis[G1.to[v]] == 1) low[u] = min(low[u],pre[G1.to[v]]); 
            }
            if(pre[u] == low[u]) {
                ++sig; 
                for(;;){
                    int a=S.top(); S.pop(); 
                    vis[a] = -1,idx[a] = sig; 
                    value[sig] += (ll)val[a]; 
                    if(a==u) break;     
                }
            }     
        }   
        void toposort(){
            for(int i=1;i<=sig;++i) 
                for(int j=G2.head[i];j;j=G2.nex[j])   ++du[G2.to[j]]; 
            for(int i=1;i<=sig;++i) if(du[i]==0) Q.push(i),ans[i] = value[i]; 
            while(!Q.empty()){
                int u=Q.front(); Q.pop(); 
                for(int v=G2.head[u];v;v=G2.nex[v]){ 
                    ans[G2.to[v]] = max(ans[G2.to[v]],ans[u] + value[G2.to[v]]); 
                    --du[G2.to[v]]; 
                    if(du[G2.to[v]]==0) Q.push(G2.to[v]); 
                }
            }
            long long fin=0; 
            for(int i=1;i<=sig;++i) 
                fin=max(fin,ans[i]); 
            printf("%lld",fin); 
        }
        int main(){
            int n,m,a,b; 
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;++i) scanf("%d",&val[i]);     
            for(int i=1;i<=m;++i) {   
                scanf("%d%d",&a,&b);      
                G1.addedge(a,b); 
            }
            for(int i=1;i<=n;++i) if(!vis[i]) tarjan(i);                       
            for(int i=1;i<=n;++i) 
                for(int v=G1.head[i];v;v=G1.nex[v])
                    if(idx[i]!=idx[G1.to[v]] && !ed[idx[i]][idx[G1.to[v]]])  
                        G2.addedge(idx[i],idx[G1.to[v]]),ed[idx[i]][idx[G1.to[v]]]=1;    
            toposort(); 
            return 0; 
        }
    }; 
    int main(){
        Tarjan::main(); 
        return 0; 
    }
    

      

  • 相关阅读:
    umask
    mysql 错误总结 和FROM_UNIXTIME用法
    php 读取和下载execl
    Yii 2 load() 和 save()
    iframe 模拟ajax文件上传and formdata ajax 文件上传
    angular.js简单入门。
    mysql 慢日志
    mysql 基本操作 alter
    shell cut 用法
    微信支付与支付宝支付
  • 原文地址:https://www.cnblogs.com/guangheli/p/10658410.html
Copyright © 2011-2022 走看看