模板:缩点

翻之前记录翻出来缩点的板子

正好今天语文课看tarjan睡着了……

https://www.luogu.org/problemnew/show/P3387

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 using namespace std;
 5 const int maxn=10000+10;
 6 int n, m, cnt, num, s, top;
 7 int v[maxn], dfn[maxn], low[maxn], sd[maxn];
 8 int st[maxn], vis[maxn], d[maxn];
 9 int h[maxn], head[maxn], in[maxn];
10 struct qwq{
11     int to, next, from;
12 }edge[maxn*10], ed[maxn*10];
13 void add(int x,int y){
14     edge[++cnt].next=head[x];
15     edge[cnt].from=x;
16     edge[cnt].to=y;
17     head[x]=cnt;
18 }
19 void tarjan(int x){
20     dfn[x]=low[x]=++num;
21     st[++top]=x;
22     vis[x]=1;
23     for(int i=head[x];i;i=edge[i].next){
24         int v=edge[i].to;
25         if(!dfn[v]){
26             tarjan(v);
27             low[x]=min(low[x],low[v]);
28         }
29         else if(vis[v]){
30             low[x]=min(low[x],dfn[v]);
31         }
32     }
33     if(dfn[x]==low[x]){
34         int y;
35         while(y=st[top--]){
36             sd[y]=x;
37             vis[y]=0;
38             if(x==y) break;
39             v[x]+=v[y];
40         }
41     }
42 }
43 int toposort(){
44     queue <int> q;
45     int tot=0;
46     for(int i=1; i<=n; i++)
47         if(sd[i]==i && !in[i]){
48         q.push(i);
49         d[i]=v[i];
50     } 
51     while(!q.empty()){
52         int k=q.front();
53         q.pop();
54         for(int i=h[k]; i; i=ed[i].next){
55             int a=ed[i].to;
56             d[a]=max(d[a], d[k]+v[a]);
57             in[a]--;
58             if(in[a]==0) q.push(a);
59         }
60     }
61     int ans=0;
62     for(int i=1; i<=n; i++) ans=max(ans,d[i]);
63     return ans;
64 }
65 int main(){
66     cin>>n>>m; 
67     for(int i=1; i<=n; i++){
68         cin>>v[i];
69     }
70     for(int i=1; i<=m; i++){
71         int u, v;
72         cin>>u>>v;
73         add(u, v);
74     }
75     for(int i=1; i<=n; i++){
76         if(!dfn[i]) tarjan(i);
77     }
78     for(int i=1; i<=m; i++){
79         int x=sd[edge[i].from],y=sd[edge[i].to];
80         if(x!=y){
81             ed[++s].next=h[x];
82             ed[s].to=y;
83             ed[s].from=x;
84             h[x]=s;
85             in[y]++;
86         }
87     }
88     cout<<toposort()<<endl;
89     return 0;
90 }
原文地址:https://www.cnblogs.com/Aze-qwq/p/9909684.html