第一次写 Tarjan,它貌似会把两个点都看成强连通分量,然后一建图就会成环,导致无法拓补排序。
#include <bits/stdc++.h>
using namespace std;
#define MAXN 10001
int n, m, u, v, cnt, ssum, ans;
int a[MAXN], sum[MAXN], f[MAXN];
int dfn[MAXN], low[MAXN], scc[MAXN];
int us[MAXN], vs[MAXN], in[MAXN];
vector<int> e[MAXN];
bitset<MAXN> ins;
stack<int> st;
queue<int> que;
void tarjan(int x){
low[x] = dfn[x] = ++cnt;
st.push(x);
for (auto i: e[x]){
if (!dfn[i]){
tarjan(i);
low[x] = min(low[x], low[i]);
}else if (ins.test(i)){
low[x] = min(low[x], dfn[i]);
}
}
if (dfn[x] == low[x]){
scc[x] = ++ssum;
sum[ssum] = a[x];
while (st.top() != x){
scc[st.top()] = ssum;
ins.reset(st.top());
sum[ssum] += a[st.top()];
st.pop();
}
st.pop();
ins.reset(x);
}
}
void topsort(){
for (int i(1); i<=ssum; ++i){
if (!in[i]){
que.push(i);
f[i] = sum[i];
}
}
while (!que.empty()){
u = que.front();
que.pop();
for (auto v: e[u]){
f[v] = max(f[v], f[u]+sum[v]);
if (!(--in[v])) que.push(v);
}
ans = max(ans, f[u]);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i(1); i<=n; ++i) cin >> a[i];
for (int i(1); i<=m; ++i){
cin >> u >> v;
us[i] = u;
vs[i] = v;
e[u].push_back(v);
}
for (int i(1); i<=n; ++i){
if (!dfn[i]) tarjan(i);
}
for (int i(1); i<=n; ++i) e[i].clear();
for (int i(1); i<=m; ++i){
u = scc[us[i]];
v = scc[vs[i]];
if (u != v){
e[u].push_back(v);
++in[v];
}
}
topsort();
cout << ans;
return 0;
}