从起点开始,按照拓扑排序的顺序依次更新dp[i],表示到该点能获得的最大值
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll __int64
#define mod 1000000007
using namespace std;
int n,m,in[100010],out[100010],v[100010],dp[100010];
vector<int> e[100010];
void topo()
{
int x,a;
for(int i=0;i<=n;i++)
dp[i]=-inf;
queue<int> q;
for(int i=1;i<=n;i++)
{
if(in[i]==0)
{
dp[i]=v[i];
q.push(i);
}
}
while(!q.empty())
{
x=q.front();
q.pop();
for(int i=0;i<e[x].size();i++)
{
a=e[x][i];
dp[a]=max(dp[a],dp[x]+v[a]);
in[a]--;
if(!in[a]) q.push(a);
}
}
}
int main()
{
int i,a,b;
while(~scanf("%d%d",&n,&m))
{
memset(in,0,sizeof in);
memset(out,0,sizeof out);
for(i=0;i<=n;i++)
e[i].clear();
for(i=1;i<=n;i++)
scanf("%d",&v[i]);
for(i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
e[a].push_back(b);
in[b]++;
out[a]++;
}
topo();
int ans=-inf;
for(int i=1;i<=n;i++)//坑点是可能不止一个起点和终点
{
if(out[i]==0)
ans=max(ans,dp[i]);
}
printf("%d\n",ans);
}
return 0;
}