P2196 [NOIP1996 提高组] 挖地雷
P2196
将题目的信息转化为图,相当于我们要在图上找一条最长路径,考虑dfs,dp[i]表示以i结尾的最长路径。则有dp[i] = max(dp[j]) + a[i]) j->i。 题目又要求输出路径,所以用pre[i]记录前驱,最后输出即可。

1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, a[25], dp[25], du[25], pre[25]; 4 //dp[i]表示到i地窖(以i结尾)挖到的最大数量 5 //du[i]记录入度 6 //pre[i]记录i的前驱 7 vector<int> e[25]; 8 void dfs(int u, int fa) { 9 for (int i = 0; i < e[u].size(); i ++) { 10 int v = e[u][i]; 11 if (v == fa) continue; 12 if (dp[v] < dp[u] + a[v]) { 13 dp[v] = dp[u] + a[v]; 14 pre[v] = u;//记录前驱 15 } 16 dfs(v, u); 17 } 18 } 19 int main() { 20 scanf("%d", &n); 21 for (int i = 1; i <= n; i ++) scanf("%d", &a[i]); 22 for (int i = 1; i < n; i ++) { 23 for (int j = i + 1; j <= n; j ++) { 24 int x; scanf("%d", &x); 25 if (x) e[i].push_back(j), du[j] ++; 26 } 27 } 28 for (int i = 1; i <= n; i ++) 29 if (!du[i]) dp[i] = a[i], dfs(i, 0); 30 int ans = 0, x = 0; 31 for (int i = 1; i <= n; i ++) { 32 if (dp[i] > ans) { 33 ans = dp[i]; 34 x = i; 35 } 36 } 37 int order[25], cnt; 38 order[++ cnt] = x; 39 while (pre[x]) { 40 order[++ cnt] = pre[x]; 41 x = pre[x]; 42 } 43 reverse(order + 1, order + cnt + 1); 44 for (int i = 1; i <= cnt; i ++) printf("%d ", order[i]); 45 //输出答案路径 46 printf("\n%d", ans);//输出最大数量 47 return 0; 48 }

浙公网安备 33010602011771号