P3387 【模板】缩点

熟悉一下基本的缩点

 1 // luogu-judger-enable-o2
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <stack>
 7 #include <vector>
 8 using namespace std;
 9 typedef pair<int, int> P;
10 const int MAXN = 1e4 + 20;
11 
12 int N, M;
13 
14 vector<P> edges;
15 vector<int> g[MAXN];
16 int dfn[MAXN], low[MAXN];
17 stack<int> sta; bool ins[MAXN];
18 int col[MAXN]; vector<int> scc[MAXN]; int cntscc;
19 int val[MAXN], sum[MAXN];
20 
21 void tarjan(int cur)
22 {
23     static int dfsclock = 0;
24     dfn[cur] = low[cur] = ++dfsclock;
25     sta.push(cur), ins[cur] = true;
26     for(int i = 0; i < (int) g[cur].size(); i++)
27     {
28         int v = g[cur][i];
29         if(!dfn[v]) {
30             tarjan(v);
31             low[cur] = min(low[cur], low[v]);
32         }
33         else if(ins[v]) low[cur] = min(low[cur], dfn[v]);
34     } 
35     if(dfn[cur] == low[cur]){
36         ++cntscc; int tmp;
37         do{
38             tmp = sta.top(); sta.pop(); ins[tmp] = false; 
39             col[tmp] = cntscc; scc[cntscc].push_back(tmp);
40             sum[cntscc] += val[tmp];
41         }while(tmp != cur);
42     }
43 }
44 
45 int f[MAXN];
46 int dfs(int cur){
47     if(f[cur]) return f[cur];
48 
49     f[cur] = sum[cur]; 
50     int maxtmp = 0;
51     for(int i = 0; i < (int) g[cur].size(); i++)
52         maxtmp = max(maxtmp, dfs(g[cur][i]));
53     return f[cur] += maxtmp;
54 }
55 
56 int main()
57 {
58     cin>>N>>M;
59     for(int i = 1; i <= N; i++) scanf("%d", &val[i]);
60     for(int i = 1, u, v; i <= M; i++){
61         scanf("%d%d", &u, &v);
62         g[u].push_back(v);
63         edges.push_back(P(u, v));
64     }
65     for(int i = 1; i <= N; i++) if(!dfn[i]) tarjan(i);
66 
67     for(int i = 0; i <= N; i++) g[i].clear();
68     for(int i = 0; i < (int) edges.size(); i++)
69         if(col[edges[i].first] != col[edges[i].second])
70             g[col[edges[i].first]].push_back(col[edges[i].second]);
71 
72     int ans = 0;
73     for(int i = 1; i <= cntscc; i++) ans = max(ans, dfs(i));
74     cout<<ans<<endl;
75     return 0;
76 }
原文地址:https://www.cnblogs.com/wsmrxc/p/9280874.html