P3387 【模板】缩点 tarjan+dp+topo
#include<cstdio>
#include<iostream>
#include<cmath>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<vector>
#include<unordered_map>
#include<stack>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f;
int mod=1000000007;
const int N=10100;
int n,m,cnt,x,y,indx,top,k;
int head[N],node[N],low[N],st[N],vis[N],dfn[N];
int a[N],in[N],dis[N];
struct edge
{
int next;
int from,to;
}e[N*10],E[N*10];
void add(int from,int to)
{
e[k].next=head[from];
e[k].from=from;
e[k].to=to;
head[from]=k++;
}
void addE(int from,int to)
{
E[k].next=head[from];
E[k].from=from;
E[k].to=to;
head[from]=k++;
}
void tarjan(int from)
{
low[from]=dfn[from]=++indx;
st[++top]=from;
vis[from]=1;
for(int i=head[from];i!=-1;i=e[i].next)
{
int to=e[i].to;
if(!dfn[to])
{
tarjan(to);
low[from]=min(low[from],low[to]);
}
else if(vis[to])
{
low[from]=min(low[from],dfn[to]);
}
}
if(dfn[from]==low[from])
{
int t;
while(1)
{
t=st[top--];
node[t]=from;
vis[t]=0;
if(from==t)break;
a[from]+=a[t];
}
}
}
int topo()
{
queue<int>q;
for(int i=1;i<=n;i++)
{
if(node[i]==i&&!in[i])
{
q.push(i);
dis[i]=a[i];
}
}
while(!q.empty())
{
k=q.front();q.pop();
for(int i=head[k];i!=-1;i=E[i].next)
{
int to=E[i].to;
dis[to]=max(dis[to],dis[k]+a[to]);
in[to]--;
if(in[to]==0)
q.push(to);
}
}
int ans=0;
for (int i=1;i<=n;i++)
ans=max(ans,dis[i]);
return ans;
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
k=0;
memset(head,-1,sizeof(head));
for(int i=0;i<m;i++)
{
x=node[e[i].from],y=node[e[i].to];
if(x!=y)
{
addE(x,y);
in[y]++;
}
}
printf("%d",topo());
return 0;
}