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 }