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 }

 

posted @ 2022-10-10 10:58  YHXo  阅读(225)  评论(0)    收藏  举报