【模板】Tarjan缩点
洛谷3387
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 const int maxn=20010,maxm=200010; 6 int ans,n,m,etot,tot,top,color,last[maxn],w[maxn],f[maxn],val[maxn],dfn[maxn],low[maxn],col[maxn],st[maxn]; 7 struct edge{int pre,to;}e[maxm]; 8 struct rec{int x,y;}a[maxm]; 9 void read(int &k){ 10 k=0; int f=1; char c=getchar(); 11 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 12 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 13 k*=f; 14 } 15 int max(int a,int b){if (a>b) return a; return b;} 16 int min(int a,int b){if (a<b) return a; return b;} 17 void add(int x,int y){e[++etot]=(edge){last[x],y}; last[x]=etot;} 18 void tarjan(int x){ 19 dfn[x]=low[x]=++tot; st[++top]=x; 20 for (int i=last[x],to;i;i=e[i].pre) 21 if (!dfn[to=e[i].to]) tarjan(to),low[x]=min(low[x],low[to]); 22 else if (!col[to]) low[x]=min(low[x],dfn[to]); 23 if (dfn[x]==low[x]) 24 for(color++;st[top+1]!=x;top--) col[st[top]]=color,val[color]+=w[st[top]]; 25 } 26 void dfs(int x){ 27 if (f[x]) return; f[x]=val[x]; int tmp=0; 28 for (int i=last[x],to;i;i=e[i].pre) dfs(to=e[i].to),tmp=max(tmp,f[to]); 29 f[x]+=tmp; 30 } 31 int main(){ 32 read(n); read(m); 33 for (int i=1;i<=n;i++) read(w[i]); 34 for (int i=1;i<=m;i++) read(a[i].x),read(a[i].y),add(a[i].x,a[i].y); 35 for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); 36 etot=0; memset(last,0,sizeof(last)); 37 for (int i=1,x,y;i<=m;i++) if(col[x=a[i].x]!=col[y=a[i].y]) add(col[x],col[y]); 38 for (int i=1;i<=color;i++) dfs(i),ans=max(ans,f[i]); 39 return printf("%d\n",ans),0; 40 }