【模板】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
",ans),0;
40 }
View Code
原文地址:https://www.cnblogs.com/DriverLao/p/7807652.html