玄学并查集+Tarjan+拓扑排序
#1#3AC,#7WA,其余MLE
#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
//#define int long long
//#define double long double
#define FOR(i,l,r) for(int i=l;i<=r;++i)
#define ROF(i,r,l) for(int i=r;i>=l;--i)
#define mkp make_pair
#define fr first
#define se second
#define pb push_back
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
using namespace std;
void IOS() {
ios::sync_with_stdio(false);
cin.tie(0);
}
void Document() {
freopen(".in","r",stdin);
freopen(".out","w",stdout);
}
inline int read(){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch^48);ch=getchar();}
return s*w;
}
inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x>9) write(x/10);
putchar(x%10+'0');
}
void Tell() {
//写数据结构注意初始化!
//浮点数类题目过不了优先考虑精度!
//vector动态开点注意内存重分配!
//有本地写freopen!没本地别写!!!
//最后几分钟给我老老实实坐那里,别手贱!!!
//long long 级别的常数运算一定要用 xll!!!
//一定要手玩几组极限数据,防止爆数。
//大数据关同步流! 大数据关同步流! 大数据关同步流!
//删调试!删调试!删调试!删调试!删调试!
//注意数据类型!注意数据类型!注意数据类型!不要把存 int 的数组开成 char 类型!
//注意数组大小的上界,不要把 5e6 打成 6e5!
}
const int N=1e4+10;
int n,m,top,t,a[N],st[N],fa[N],U[N],V[N],vis[N],dfn[N],low[N],siz[N],in[N],out[N],dp[N];
vector<int>e[N],E[N];
int Get(int x) {
return x==fa[x]?x:fa[x]=Get(fa[x]);
}
void tarjan(int x) {
st[++top]=x;
dfn[x]=low[x]=++t;
vis[x]=1;
for(int y:e[x]) {
if(!dfn[y]) {
tarjan(y);
low[x]=min(low[y],low[x]);
} else if(vis[y]) low[x]=min(low[y],low[x]);
}
if(dfn[x]==low[x]) {
while(st[top]!=x) {
if(Get(st[top])!=Get(st[top-1])) siz[Get(st[top])]+=siz[Get(st[top-1])],fa[Get(st[top-1])]=Get(st[top]);
vis[st[top]]=0;
--top;
}
vis[st[top]]=0;
--top;
}
}
void topsort() {
queue<int>q;
FOR(i,1,n) if(Get(i)==i&&!in[i]) q.push(i),dp[i]=siz[i];
while(q.size()) {
int x=q.front();q.pop();
for(int y:E[x]) {
dp[y]=max(dp[y],dp[x]+siz[y]);
if(!(--in[y])) q.push(y);
}
}
int ans=0;
FOR(i,1,n) ans=max(ans,dp[i]);
cout<<ans<<"\n";
}
main() {
cin>>n>>m;
FOR(i,1,n) a[i]=read(),fa[i]=i,siz[i]=a[i];
FOR(i,1,m) {
U[i]=read();V[i]=read();
e[U[i]].pb(V[i]);
}
FOR(i,1,n) if(!dfn[i]) tarjan(i);
FOR(i,1,m) {
if(Get(U[i])!=Get(V[i])) E[Get(U[i])].pb(Get(V[i])),in[Get(V[i])]++;
}
topsort();
return 0;
}