Luogu P3387 [Template] Indent

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

Input Example #1: Copy
2 2
1 1
1 2
2 1
Output Sample #1: Copy
2

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 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325166813&siteId=291194637