CSES - Shared codeLink to this code:
https://cses.fi/paste/d0f62ec82cb4b91269254d/
#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
using namespace std;
class CoinCollector{
vector<vector<int>>graph,flipGraph;
vector<bool>vis;
vector<int>index;
stack<int>st;
public:
vector<int>c;
CoinCollector(int n){
graph.resize(n+1);
flipGraph=graph;
vis.resize(n+1,false);
index.resize(n+1);
c=index;
}
void traverse(int u){
if(vis[u])return;
vis[u]=true;
for(int v:graph[u]){
traverse(v);
}
st.push(u);
}
void revTraverse(int u,int i){
if(vis[u])return;
vis[u]=true;
index[u]=i;
for(int v:flipGraph[u]){
revTraverse(v,i);
}
}
long long solveDP(vector<long long>&cost,vector<long long>&dp,int u,vector<int>*g){
if(dp[u]!=-1){
return dp[u];
}
long long ans=0;
for(int v:g[u]){
ans=max(ans,solveDP(cost,dp,v,g));
}
return dp[u]=ans+cost[u];
}
long long getSol(int n){
for(int i=1;i<=n;i++){
if(!vis[i]){
traverse(i);
}
}
fill(vis.begin(),vis.end(),false);
int num,ind=1;
while(!st.empty()){
num=st.top();
st.pop();
if(!vis[num]){
revTraverse(num,ind++);
}
}
fill(vis.begin(),vis.end(),false);
vector<long long>cost(ind,0),dp(ind,-1);
for(int i=1;i<=n;i++){
cost[index[i]]+=c[i];
}
long long ans=0;
vector<int>g[ind];
for(int i=1;i<=n;i++){
for(int j:graph[i]){
if(index[i]!=index[j]){
g[index[i]].push_back(index[j]);
}
}
}
for(int i=1;i<ind;i++){
ans=max(ans,solveDP(cost,dp,i,g));
}
return ans;
}
void addEdge(int a,int b){
graph[a].push_back(b);
flipGraph[b].push_back(a);
}
};
int main(){
int n,m,a,b;
cin>>n>>m;
CoinCollector sol(n);
for(int i=1;i<=n;i++){
cin>>sol.c[i];
}
for(int i=0;i<m;i++){
cin>>a>>b;
sol.addEdge(a,b);
}
cout<<sol.getSol(n);
return 0;
}