rt。
#include <iostream>
#define maxN 10100
#define maxM 100100
using namespace std;
int n, m, a[maxN], b[maxN], ans;
int max(int x, int y) {
return x > y ? x : y;
}
int head[maxN][2], nxt[maxM][2], ver[maxM][2], cnt;
void addEdge(int x, int y, bool f) {
nxt[++ cnt][f] = head[x][f]; head[x][f] = cnt; ver[cnt][f] = y;
}
bool vis[maxN];
int scc[maxN], tot;
int anc[maxN], top;
int dfn[maxN], low[maxN], idx;
void tarjan(int x) {
low[x] = dfn[x] = ++ idx;
anc[++ top] = x, vis[x] = true;
for (int i = head[x][0]; i; i = nxt[i][0]) {
int to = ver[i][0];
if (!dfn[to]) {
tarjan(to);
low[x] = min(low[x], low[to]);
}
else if (vis[to]) {
low[x] = min(low[x], dfn[to]);
}
}
if (dfn[x] == low[x]) {
int y; tot ++;
do {
y = anc[top --], vis[y] = false, scc[y] = tot, b[tot] += a[y];
} while (x ^ y);
}
}
int q[maxN], st = 1, ed;
int dist[maxN], inDegree[maxN];
void topSort() {
for (int i = 1; i <= tot; ++ i)
if (!inDegree[i]) {
q[++ ed] = i; dist[i] = b[i];
}
while (st <= ed) {
int x = q[st ++];
ans = max(ans, dist[x]);
for (int i = head[x][1]; i; i = nxt[i][1]) {
int to = ver[i][1];
dist[to] = max(dist[to], dist[x] + b[to]);
inDegree[to] --;
if (!inDegree[to]) q[++ ed] = to;
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++ i) cin >> a[i];
for (int i = 1, u, v; i <= m; ++ i) {
cin >> u >> v; addEdge(u, v, 0);
}
for (int i = 1; i <= n; ++ i)
if (!dfn[i]) tarjan(i);
cnt = 0;
for (int x = 1; x <= n; ++ x)
for (int i = head[x][0]; i; i = nxt[x][0]) {
int to = ver[i][0];
if (scc[x] == scc[to]) continue;
addEdge(scc[x], scc[to], 1), inDegree[scc[to]] ++;
}
topSort();
cout << ans << '\n';
return 0;
}