Title Source:
Title Description:
Background of topic
Shrinkage point +DP
Title Description
Given a directed graph with n points and m edges, each point has a weight, and a path is found to maximize the sum of the weight of the points that the path passes through. You just need to find the sum of the weights.
It is allowed to pass an edge or a point multiple times. However, for a point that passes repeatedly, the weight is only calculated once.
I / O format
Input format:
First line, n,m
The second line, n integers, represents point weight in turn
The third to m+2 lines, each line has two integers u,v, indicating that u - > V has a directed edge
Output format:
A total of one line, the largest sum of point weights.
Explain
N < = 10 ^ 4, m < = 10 ^ 5, point weight < = 1000
Algorithm: Tarjan shrink point + DAGdp
Solutions:
Don't talk about tarjan shrinking point. The key is to find the maximum point weight. I use the memory search, but I don't know very well. But it's finally passed under the reference of many parties. After remembering the shrinking point, the weight of each point is the sum of the point weights for the strongly connected components...
Code:
#include <iostream> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <vector> #include <queue> #include <stack> using namespace std; int dfn[10005],low[10005],f[10005],quan[10005],lt[10005],fl[10005],rd[10005],cd[10005],tot,gs; bool vis[10005],ins[10005],jl[10005]; stack<int>s; vector<int>E[10005],E1[10005]; int n,m; void tarjan(int u) { dfn[u]=low[u]=++tot; ins[u]=vis[u]=1; s.push(u); for(int i=0;i<E[u].size();i++) { int v=E[u][i]; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(ins[v]){ low[u]=min(low[u],dfn[v]); } } if(dfn[u]==low[u]){ gs++; while(1){ int now=s.top(); s.pop(); fl[gs]+=quan[now]; lt[now]=gs; ins[now]=0; vis[now]=0; if(now==u)break; } } } void dp(int x){ //Memorize search on DAG / / you can also use spfa to find the longest path if(f[x]) return ; f[x]=fl[x]; int maxsum = 0; for(int i=0;i<E1[x].size();i++){ if(!f[E1[x][i]]) dp(E1[x][i]); maxsum=max(maxsum,f[E1[x][i]]); } f[x]+=maxsum; } int main() { cin>>n>>m; for(int i=1;i<=n;i++) cin>>quan[i]; for(int i=1;i<=m;i++) { int a,b; cin>>a>>b; E[a].push_back(b); } tot=gs=0; for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i); int ans=0; for(int i=1;i<=n;i++) { for(int j=0;j<E[i].size();j++) { int v=E[i][j]; if(lt[i]==lt[v])continue; E1[lt[i]].push_back(lt[v]); cd[lt[i]]++;rd[lt[v]]++; } } for(int i=1;i<=gs;i++){ if(!f[i]){ dp(i); ans=max(ans,f[i]); } } cout<<ans<<endl; return 0; }