P3387 【模板】缩点


复习一下scc


#include<bits/stdc++.h>
using namespace std;
const int bw=1000001;
int head[bw],head2[bw],low[bw],rd[bw],vist[bw],f[bw],nc[bw],vd[bw],dfn[bw],val[bw];
int ne,n,deep,color,a,b,m,ans=-1;
struct node{int nxt,v;}eg[bw],eg2[bw];
stack<int>s;queue<int>q;
void adde(int a,int b){eg[++ne].v=b;eg[ne].nxt=head[a];head[a]=ne;}
void addee(int a,int b){eg2[++ne].v=b;eg2[ne].nxt=head2[a];head2[a]=ne;rd[b]++;}
void dfs(int u){low[u]=dfn[u]=++deep;s.push(u);vist[u]=1;
    for(int i=head[u];i;i=eg[i].nxt){
        int g=eg[i].v;
        if(!dfn[g]){dfs(g);low[u]=min(low[u],low[g]);}
        else if(vist[g])low[u]=min(low[u],dfn[g]);
    }
    if(dfn[u]==low[u]){color++;
        while(s.top()!=u){nc[s.top()]=color;vist[s.top()]=0;vd[color]+=val[s.top()];s.pop();}
        nc[u]=color;vist[u]=0;s.pop();vd[color]+=val[u];
    }
}
void topo()
{    
    for(int i=1;i<=color;i++){f[i]=vd[i];if(!rd[i])q.push(i);}
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(int i=head2[u];i;i=eg2[i].nxt)
        {
            int v=eg2[i].v;
            f[v]=max(f[v],f[u]+vd[v]);
            if(!--rd[v])q.push(v);
        }
    }
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>val[i];
    for(int i=1;i<=m;i++){cin>>a>>b;adde(a,b);}ne=0;
    for(int i=1;i<=n;i++)if(!dfn[i])dfs(i);
    for(int i=1;i<=n;i++)for(int j=head[i];j;j=eg[j].nxt)
    if(nc[i]!=nc[eg[j].v])addee(nc[i],nc[eg[j].v]);
    topo();
    for(int i=1;i<=color;i++)ans=max(ans,f[i]);
    cout<<ans;
}
原文地址:https://www.cnblogs.com/SFWR-YOU/p/11853572.html