#include<bits/stdc++.h>
#define maxn 10005
#define maxx 200005
using namespace std;
struct eee{
int to;
int next;
}edge[maxx],e[maxx];
int cnt,n,m,root[maxn],dfn[maxn],low[maxn],s[maxn],top,visted[maxn],num[maxn],value[maxn],svalue[maxn],degree[maxn],tot;
int ans,deep,root2[maxn],res[maxn],cnt2;
stack<int>ss;
void add1(int x,int y){
edge[++cnt].to=y;
edge[cnt].next=root[x];
root[x]=cnt;
}
void add2(int x,int y){
degree[y]++;
e[++cnt2].to=y;
e[cnt2].next=root2[x];
root2[x]=cnt2;
}
void tarjan(int u){
dfn[u]=++deep;
low[u]=deep;
s[++top]=u;
visted[u]=1;
for(int i=root[u];i;i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(visted[u]){
low[u]=min(low[u],low[v]);
}
}
if(low[u]==dfn[u]){
num[u]=++tot;
visted[u]=0;
while(s[top]!=u){
visted[s[top]]=0;
num[s[top--]]=tot;
}
top--;
}
}
int main(){
freopen("1.in","r",stdin);
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>value[i];
}
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
add1(x,y);
}
for(int i=1;i<=n;i++){
if(!dfn[i])tarjan(i);
}
for(int i=1;i<=n;i++){
if(num[i]==0){num[i]=++tot;}
svalue[num[i]]+=value[i];
}
for(int i=1;i<=n;i++){
for(int j=root[i];j;j=edge[j].next){
int v=edge[j].to;
if(num[i]!=num[v]){
add2(num[i],num[v]);
}
}
}
for(int i=1;i<=tot;i++){
if(degree[i]==0){
ss.push(i);
res[i]=svalue[i];
}
//printf("%d ",degree[i]);
}
//for(int i=1;i<=tot;i++)printf("%d ",svalue[i]);
while(!ss.empty()){
int x=ss.top();
ss.pop();
for(int i=root2[x];i;i=e[i].next){
int v=e[i].to;
res[v]=max(svalue[v]+res[x],res[v]);
ans=max(ans,res[v]);
degree[v]--;
if(degree[v]==0)ss.push(v);
}
}
if(ans==0)ans=svalue[1];
//printf("%d\n",svalue[1]);
printf("%d\n",ans);
return 0;
}
思路非常清晰,先求强连通分量然后通过缩点把图转换成DAG。最后对DAG进行拓扑排序然后dp就直接出了,但是两个点卡了,并且实在是不太会调了,目测是细节问题。。。。