需要用拓扑排序解决dp的无后效性
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int head[maxn];
int dfn[maxn];
int low[maxn];
bool vis[maxn];
int colour[maxn];
int dv[maxn];
int indu[maxn];
int dist[maxn];
int tot;
int tot1;
int dex;
int cnt;
int n, m;
int ans;
struct node{
int to;
int next;
int from;
node() {}
node(int a, int b, int c) : to(a), next(b), from(c) {}
}edge[maxn], edge1[maxn];
void edgeadd(int a, int b){
edge[tot] = node(b, head[a], a);
head[a] = tot++;
}
void edgeadd1(int a, int b){
edge1[tot1] = node(b, head[a], a);
head[a] = tot1++;
}
void init(){
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
memset(dfn, 0, sizeof(dfn));
memset(indu, 0, sizeof(indu));
tot = 0;
tot1 = 0;
dex = 0;
ans = 0;
}
stack<int> s;
void tarjan(int u){
dfn[u] = low[u] = ++dex;
s.push(u);
vis[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].to;
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]){
while(1){
int now = s.top();
//cout << now << endl;
colour[now] = u;
s.pop();
vis[now] = 0;
if(now == u) break;
dv[u] += dv[now];
}
}
}
int topu(){
queue<int> q;
for(int i = 1; i <= n; i++){
if(colour[i] == i && !indu[i]){
q.push(i);
dist[i] = dv[i];
}
}
while(!q.empty()){
int now = q.front();
q.pop();
for(int i = head[now]; i != -1; i = edge1[i].next){
int v = edge1[i].to;
dist[v] = max(dist[v], dist[now] + dv[v]);
indu[v]--;
if(indu[v] == 0)
q.push(v);
}
}
int ans1 = 0;
for (int i = 1; i <= n; i++)
ans1 = max(ans1, dist[i]);
return ans1;
}
int main(){
ios::sync_with_stdio(false);
while(cin >> n >> m){
init();
int x, y;
for(int i = 1; i <= n; i++){
cin >> dv[i];
}
for(int i = 1; i <= m; i++){
cin >> x >> y;
edgeadd(x, y);
}
for(int i = 1; i <= n; i++){
if(!dfn[i])
tarjan(i);
}
memset(head, -1, sizeof(head));
for(int i = 0; i < m; i++){
int o, g;
o = colour[edge[i].from];
g = colour[edge[i].to];
if(o != g){
edgeadd1(o, g);
indu[g]++;
}
}
cout << topu() << endl;
}
return 0;
}