topic background
Zoom point + DP
Topic description
Given a directed graph with n points and m edges, each point has a weight, find a path that maximizes the sum of the weights of the points that the path passes through. You just ask for this sum of weights.
It is allowed to pass through an edge or a point multiple times, but the weights are only calculated once for the repeatedly passed points.
Input and output format
Input format:
first line, n,m
The second line, n integers, in turn represent point weights
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.
Input and output example
illustrate
n<=10^4,m<=10^5,点权<=1000
Algorithm: Tarjan contraction point + DAGdp
1 //2018年4月30日17:48:17 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 7 const int N = 100001; 8 const int M = 500001; 9 10 int n, m, w[N], ans; 11 12 int fir[N], to[M], nxt[M], edge_num; 13 void addEdge(int x, int y){ 14 to[++edge_num] = y; 15 nxt[edge_num] = fir[x]; 16 fir[x] = edge_num; 17 } 18 19 int dfn[N], low[N], stack[N], top, instack[N], tim, col_num, color[N], sum[N]; 20 void Tarjan(int x){ 21 low[x] = dfn[x] = ++tim; 22 stack[++top] = x; 23 instack[x] = 1; 24 for(int i=fir[x]; i; i=nxt[i]){ 25 int v = to[i]; 26 if(!dfn[v]){ 27 Tarjan(v); 28 low[x] = min(low[x], low[v]); 29 }else if(instack[v]){ 30 low[x] = min(low[x], dfn[v]); 31 } 32 } 33 if(low[x] == dfn[x]){ 34 col_num++; 35 while(1){ 36 int now = stack[top--]; 37 instack[now] = 0; 38 color[now] = col_num; 39 sum[col_num] += w[now]; 40 if(now == x) break; 41 } 42 } 43 } 44 45 int dp[N]; 46 47 int dfs(int u){ 48 if(dp[u]) return dp[u]; 49 dp[u] = sum[u]; 50 int mx = 0; 51 for(int i=fir[u]; i; i=nxt[i]){ 52 int v = to[i]; 53 if(!dp[v]) dfs(v); 54 if(dp[v] > mx) mx = dp[v]; 55 } 56 dp[u] += mx; 57 return dp[u]; 58 } 59 60 int main(){ 61 scanf("%d%d", &n, &m); 62 for(int i=1; i<=n; i++) 63 scanf("%d", &w[i]); 64 int x[N], y[N]; 65 for(int i=1; i<=m; i++){ 66 scanf("%d%d", &x[i], &y[i]); 67 addEdge(x[i], y[i]); 68 } 69 for(int i=1; i<=n; i++) 70 if(!dfn[i]) 71 Tarjan(i); 72 memset(fir, 0, sizeof(fir)); 73 memset(to, 0, sizeof(to)); 74 memset(nxt, 0, sizeof(nxt)); 75 edge_num = 0; 76 for(int i=1; i<=m; i++) 77 if(color[x[i]] != color[y[i]]) 78 addEdge(color[x[i]], color[y[i]]); 79 for(int i=1; i<=col_num; i++) 80 if(!dp[i]){ 81 dfs(i); 82 ans = max(ans, dp[i]); 83 } 84 printf("%d\n" , years); 85 86 return 0 ; 87 }