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; }