思路是tarjan缩点然后dp,应该不需要拓扑排序吧。。。
#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, b, a) for (int i = b; i >= a; i--)
using namespace std;
using pii = pair<int, int>;
using graph = vector<vector<pii>>;
using ugraph = vector<vector<int>>;
using ll = long long;
constexpr int MAXN = 2E5 + 5;
constexpr ll INF = 1E18;
int tim, tot; // 时间戳, scc个数
stack<int> st;
bool in_stack[MAXN];
int dfn[MAXN], low[MAXN], num[MAXN], color[MAXN], sum[MAXN];
void tarjan(int x, ugraph &g) {
st.push(x), in_stack[x] = true;
dfn[x] = low[x] = ++tim;
for (auto y : g[x]) {
if (dfn[y] == 0) {
tarjan(y, g);
low[x] = min(low[x], low[y]);
} else if (in_stack[y]) {
low[x] = min(low[x], low[y]);
}
}
if (dfn[x] == low[x]) {
tot++;
while (st.top() != x) {
sum[tot] += num[st.top()];
color[st.top()] = tot;
st.pop(), in_stack[x] = false;
}
sum[tot] += num[x];
color[x] = tot;
st.pop(), in_stack[x] = false;
}
}
int dp[MAXN];
void dfs(int x, ugraph &g) {
dp[x] = sum[x];
int res = 0;
for (int y : g[x]) {
if (!dp[y]) dfs(y, g);
res = max(res, dp[y]);
}
dp[x] += res;
}
int u[MAXN], v[MAXN];
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr);
int n, m;
cin >> n >> m;
ugraph g(n + 1);
for (int i = 1; i <= n; i++) {
cin >> num[i];
}
for (int i = 1; i <= m; i++) {
cin >> u[i] >> v[i];
g[u[i]].emplace_back(v[i]);
}
for (int i = 1; i <= n; i++) {
if (!dfn[i]) tarjan(i, g);
}
ugraph h(n + 1);
for (int i = 1; i <= m; i++) {
if (color[u[i]] != color[v[i]]) {
h[color[u[i]]].emplace_back(color[v[i]]);
}
}
for (int i = 1; i <= tot; i++) {
if (!dp[i]) dfs(i, h);
}
int ans = 0;
for (int i = 1; i <= tot; i++) {
ans = max(ans, dp[i]);
}
cout << ans;
return 0;
}