#include <bits/stdc++.h> // 借鉴了蓝书和题解
using namespace std;
const int N = 1e5 + 5, M = 1e6 + 5;
int dfn[N], low[N], sta[N], c[N]; // c[x] x所在强联通分量的编号
bool vis[N];
vector <int> scc[N], e[N], e2[N]; // 编号为i的强联通分量的所有点
int n, m, _dfn, top, cnt;
int a[N], a2[N];
void tarjan(int u) {
dfn[u] = low[u] = ++ _dfn;
sta[++top] = u;
vis[u] = 1;
for (int v : e[u])
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
} else if (vis[v]) low[u] = min(low[u], dfn[v]);
if (low[u] == dfn[u]) {
cnt ++;
int v;
do {
v = sta[top --];
vis[v] = 0;
c[v] = cnt;
a2[cnt] += a[v];
scc[cnt].push_back(v);
} while (v != u);
}
}
int in[N], f[N];
queue <int> q;
void topo() {
while (q.size()) {
int u = q.front();
q.pop();
for (int v : e2[u]) {
f[v] = max(f[v], f[u] + a2[v]);
if (--in[v] == 0) {
q.push(v);
}
}
}
}
int main() {
cin.tie(0); ios::sync_with_stdio(0);
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
while (m--) {
int u, v; cin >> u >> v;
e[u].push_back(v);
}
for (int i = 1; i <= n; i++)
if (!dfn[i]) tarjan(i);
for (int u = 1; u <= n; u++)
for (int v : e[u]) {
if (c[u] == c[v]) continue;
e2[c[u]].push_back(c[v]);
in[c[v]] ++;
}
for (int i = 1; i <= cnt; i++) if (!in[i]) q.push(i), f[i] = a2[i];
topo();
int ans = 0;
for (int i = 1; i <= cnt; i++) ans = max(ans, f[i]);
cout << ans;
return 0;
}
第 70 行写成 in[v] ++;
都能有 60 分……
新图的东西不要和旧图搞混了,尤其是缩点后的节点和新边