缩点求DAG最长路
tarjan缩点:给一个强连通分量内的点打标记,缩为新的点,建立新的图( DAG )
#include <bits/stdc++.h>
using namespace std ;
const int N=1e4+2;
int n,m,a[N];
int pool,low[N],dfn[N];
int cl,col[N];
int f[N],val[N];
vector<int> g[N],graph[N];
stack<int> st;
void tarjan(int x){
st.push(x);
dfn[x]=low[x]=++pool;
int i,y;
for(i=0;i<g[x].size();i++){
y=g[x][i];
if(!dfn[y]) tarjan(y),low[x]=min(low[x],low[y]);
else if(!col[y]) low[x]=min(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
cl++;
do{
y=st.top(); st.pop();
col[y]=cl;
}while(x!=y);
}
}
int dp(int x){
if(f[x]!=-1) return f[x];
f[x]=val[x];
for(int i=0,y;i<graph[x].size();i++){
y=graph[x][i];
f[x]=max(f[x],val[x]+dp(y));
}
return f[x];
}
int main(){
int i,j,x,y,t=0;
cin>>n>>m;
for(i=1;i<=n;i++) cin>>a[i];
for(i=1;i<=m;i++) cin>>x>>y,g[x].push_back(y);
for(i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
for(i=1;i<=n;i++) val[col[i]]+=a[i];
for(i=1;i<=n;i++)
for(j=0;j<g[i].size();j++){
x=col[i],y=col[g[i][j]];
if(x!=y) graph[x].push_back(y);
}
for(i=1;i<=cl;i++) f[i]=-1;
for(i=1;i<=cl;i++) t=max(t,dp(i));
cout<<t;
}
浙公网安备 33010602011771号