缩点
这个就是最基本的了.
主要是用来造出DAG然后跑个topo之类的DP
#include <bits/stdc++.h>
#define mod 23333
#define ll long long
#define F(i,i0,n) for(int i=i0;i<=n;i++)
#define N 600005
#define M 1000005
using namespace std;
inline int rd(){
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int p[M],id;
struct edge{
int u,v,nt;
}e[M];
void add(int x,int y){
e[++id]={x,y,p[x]};
p[x]=id;
}
int n,m,a[N],dfn[N],low[N],st[N],top,num,co[N],val[N],col;
void Tanjan(int u){
dfn[u]=low[u]=++num;
st[++top]=u;
for(int i=p[u];i;i=e[i].nt){
int v=e[i].v;
if(!dfn[v]){
Tanjan(v);
low[u]=min(low[u],low[v]);
}
else if(!co[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
co[u]=++col;
val[col]+=a[u];
while(st[top]!=u){
co[st[top]]=col;
val[col]+=a[st[top]];
--top;
}
--top;
}
}
int d[N],s[N];
int main() {
n=rd(),m=rd();
F(i,1,n)a[i]=rd();
F(i,1,m){
int x=rd(),y=rd();
add(x,y);
}
for(int i=1;i<=n;i++){
if(!dfn[i])Tanjan(i);
}
memset(p,0,sizeof(p));
id=0;
for(int i=1;i<=m;i++){
int u=e[i].u,v=e[i].v;
if(co[u]!=co[v]){
add(co[u],co[v]);
d[co[v]]++;
}
}
queue<int>q;
for(int i=1;i<=col;i++){
if(!d[i])q.push(i),s[i]=val[i];
}
int ans=0;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=p[u];i;i=e[i].nt){
int v=e[i].v;
s[v]=max(s[v],s[u]+val[v]);
if(--d[v]==0)q.push(v);
}
ans=max(ans,s[u]);
}
cout<<ans<<endl;
return 0;
}

浙公网安备 33010602011771号