P3387 【模板】缩点
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
int n,m,dfn[10010],low[10010],cnt,sccno[10010],cntsccno,indeg[10010];
ull a[10010],a2[10010],dp[10010],ans;
vector<int> g[10010],g2[10010];
stack<int> s;
bool instack[10010];
queue<int> q;
void tarjan(int u,int fa) {
low[u] = dfn[u] = ++cnt;
s.push(u);
instack[u] = true;
for (int i = 0;i < g[u].size();i ++) {
int v = g[u][i];
if (!dfn[v]) {
tarjan(v,u);
low[u] = min(low[u],low[v]);
} else if (instack[v]) low[u] = min(low[u],dfn[v]);
}
if (low[u] == dfn[u]) {
++ cntsccno;
while (s.top() != u) {
sccno[s.top()] = cntsccno;
a2[cntsccno] += a[s.top()];
s.pop();
}
sccno[s.top()] = cntsccno;
a2[cntsccno] += a[s.top()];
s.pop();
}
return;
}
void build_g2() {
for (int i = 1;i <= n;i ++)
for (int j = 0;j < g[i].size();j ++) {
int v = g[i][j];
if (sccno[i] != sccno[j]) {
g2[sccno[i]].push_back(sccno[v]);
++ indeg[sccno[v]];
}
}
return;
}
void toposort() {
for (int i = 1;i <= cntsccno;i ++) {
if (!indeg[i]) {
q.push(i);
dp[i] = a2[i];
}
}
while (!q.empty()) {
int u = q.front();
q.pop();
for (int i = 0;i < g2[u].size();i ++) {
int v = g2[u][i];
-- indeg[v];
dp[v] = max(dp[v],dp[u] + a2[v]);
if (!indeg[v]) {
q.push(v);
}
}
}
ans = 0;
for (int i = 1;i <= n;i ++)
ans = max(ans,dp[i]);
return;
}
int main() {
scanf("%d%d",&n,&m);
for (int i = 1;i <= n;i ++)
scanf("%llu",&a[i]);
for (int i = 1;i <= m;i ++) {
int ut,vt;
scanf("%d%d",&ut,&vt);
g[ut].push_back(vt);
}
for (int i = 1;i <= n;i ++)
if (!dfn[i]) tarjan(i,0);
build_g2();
toposort();
printf("%llu\n",ans);
return 0;
}