蓝桥杯 结点选择
Posted 王宜鸣
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯 结点选择相关的知识,希望对你有一定的参考价值。
思路:
无根树转有根树 + 树形dp。
实现:
1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 const int MAXN = 100000; 9 const int INF = 0x3f3f3f3f; 10 11 int n, x, y; 12 int dp[MAXN + 5][2], a[MAXN + 5], f[MAXN + 5], vis[MAXN + 5]; 13 vector<int> G[MAXN + 5]; 14 15 void trans(int root, int p) 16 { 17 for (int i = 0; i < G[root].size(); i++) 18 { 19 int tmp = G[root][i]; 20 if (tmp != p) 21 trans(tmp, f[tmp] = root); 22 } 23 } 24 25 void build() 26 { 27 for (int i = 1; i <= n; i++) 28 G[i].clear(); 29 for (int i = 2; i <= n; i++) 30 { 31 G[f[i]].push_back(i); 32 } 33 } 34 35 void dfs(int now) 36 { 37 vis[now] = 1; 38 for (int i = 0; i < G[now].size(); i++) 39 { 40 int tmp = G[now][i]; 41 if (!vis[tmp]) 42 { 43 dfs(tmp); 44 } 45 dp[now][1] += dp[tmp][0]; 46 dp[now][0] += max(dp[tmp][1], dp[tmp][0]); 47 } 48 dp[now][1] += a[now]; 49 } 50 51 int main() 52 { 53 cin >> n; 54 for (int i = 1; i <= n; i++) 55 { 56 scanf("%d", &a[i]); 57 } 58 for (int i = 0; i < n - 1; i++) 59 { 60 scanf("%d %d", &x, &y); 61 G[x].push_back(y); 62 G[y].push_back(x); 63 } 64 int ans = -INF; 65 trans(1, -1); 66 build(); 67 memset(dp, 0, sizeof(dp)); 68 memset(vis, 0, sizeof(vis)); 69 dfs(1); 70 ans = max(ans, max(dp[1][0], dp[1][1])); 71 printf("%d\n", ans); 72 return 0; 73 }
以上是关于蓝桥杯 结点选择的主要内容,如果未能解决你的问题,请参考以下文章