缩点

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=10005;
ll n,m,sum,tim,top,s;
ll p[maxn],head[maxn],sd[maxn],dfn[maxn],low[maxn];
ll stac[maxn],vis[maxn];
ll h[maxn],in[maxn],dist[maxn];
struct st {
    int to;
    int next;
    int from;
}edge[maxn*10],ed[maxn*10];
void add(int x,int y){
    edge[++sum].next=head[x];
    edge[sum].from=x;
    edge[sum].to=y;
    head[x]=sum;
}
void tarjan(int x){
    low[x]=dfn[x]=++tim;
    stac[++top]=x;
    vis[x]=1;
    for(int i=head[x];i;i=edge[i].next){
        int v=edge[i].to;
        if(!dfn[v]){
            tarjan(v);
            low[x]=min(low[x],low[v]);
        }
        else if(vis[v]){
            low[x]=min(low[x],low[v]);    
        }
    }
    if(dfn[x]==low[x]){
        int y;
        while(y=stac[top--]){
            sd[y]=x;
            vis[y]=0;
            if(x==y){
                break;
            }
            p[x]+=p[y];
        }
    }
}
ll topo(){
    queue<int >q;
    int tot=0;
    for(int i=1;i<=n;i++){
        if(sd[i]==i&&!in[i]){
            q.push(i);
            dist[i]=p[i];
        }
    }
    while(!q.empty()){
        int temp=q.front();
        q.pop();
        for(int i=h[temp];i;i=ed[i].next){
            int v=ed[i].to;
            dist[v]=max(dist[v],dist[temp]+p[v]);
            in[v]--;
            if(in[v]==0)q.push(v);
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++){
        ans=max(ans,dist[i]);
    }
    return ans;
}
void solve(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>p[i];
    for(int i=1;i<=m;i++){
        ll u,v;
        cin>>u>>v;
        add(u,v);
    }
    for(int i=1;i<=n;i++){
        if(!dfn[i]){
            tarjan(i);
        }
    }
    for(int i=1;i<=m;i++){
        int x=sd[edge[i].from],y=sd[edge[i].to];
        if(x!=y){
            ed[++s].next=h[x];
            ed[s].to=y;
            ed[s].from=x;
            h[x]=s;
            in[y]++;
        }
    }
    cout<<topo()<<endl;
}
int main(){
    ios::sync_with_stdio(false);cin.tie(0);
//    freopen("1.in","r",stdin);
//    getlist(1e7);
    int t=1;
    //cin>>t;
    while(t--){
        solve();
    }
    
}
rush!
原文地址:https://www.cnblogs.com/LH2000/p/14823884.html