有注释比较易懂
#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
#define maxm 100005
#define ll long long
int read(){
int x=0;
int f=1;
char c=getchar();
while(c>'9'||c<'0'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=(x<<1)+(x<<3)+(c^'0');
c=getchar();
}
return x*f;
}
vector<int>g[maxn];//original gragh
vector<int>g1[maxn];//super gragh
int color[maxn];//color the super point
int vis[maxn];//in or not in stack
int stack_[maxn];//stack
int dfn[maxn];//time mark
int low[maxn];//fathers' time that you can get the earliest
int val_[maxn];//super point val
int val[maxn];//point val
int deep, sum, index_;
//time,super point number,,stack top
int n,m;
int dp[maxn];
//final dp ans;
void tarjan( int now ){
dfn[now] = ++ deep ;
low[now] = deep ;
vis[now] = 1 ;
stack_[++index_]=now;
// cerr<<now<<' '<<deep<<' '<<dfn[now]<<endl;
for(int i=0;i<g[now].size();i++){
int to = g[now][i];
if(!dfn[to]){
tarjan(to);
low[now] = min(low[now],low[to]);
}else{
if(vis[to]){
low[now] = min(low[now],low[to]);
}
}
}
if(dfn[now]==low[now]){
sum++;
while(1){
color[stack_[index_]]=sum;
vis[stack_[index_]]=0;
val_[sum]+=val[stack_[index_]];
index_--;
if(now==stack_[index_+1])break;
}
}
}
void dps(int now){
if(dp[now])return;
dp[now]=val_[now];
int max_dp=0;
for(int i=0;i<g1[now].size();i++){
if(!dp[g1[now][i]])dps(g1[now][i]);
max_dp=max(max_dp,dp[g1[now][i]]);
}
dp[now]+=max_dp;
}
void debug(){
for(int i=1;i<=n;i++)cerr<<i<<' '<<dfn[i]<<' ';
cerr<<endl;
}
int main(){
n=read();
m=read();
for(int i=1;i<=n;i++){
val[i]=read();
}//in val
for(int i=1,u,v;i<=m;i++){
u=read();
v=read();
g[u].push_back(v);
}//build original gragh
for(int i=1;i<=n;i++){
if(!dfn[i]){
// cerr<<"tar";
tarjan(i);
}
}// do tarjan on each point
// debug();
for(int i=1;i<=n;i++){
for(int j=0;j<g[i].size();j++){
int to=g[i][j];
if(color[i]!=color[to]){
g1[i].push_back(to);
}
}
}//build new super gragh
int final_ans=0;
for(int i=1;i<=sum;i++){
if(!dp[i]){
dps(i);
final_ans=max(final_ans,dp[i]);
}
}//make dp on each super point
cout<<final_ans;
return 0;
}