ProgMe

Codeforces_forever Round #1 (Div3) F

Apr 25th, 2020
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.13 KB | None | 0 0
  1. //решение
  2. Эта задача на технику «переподвешивания». Сначала давайте посчитаем ответ для какого-то фиксированного корня. Как мы можем это сделать? Пусть dpv равно максимально возможной разницы между количеством белых и черных вершин в каком-то таком поддереве v (да, поддерево коревого дерева, то есть v и все ее прямые и косвенные дети), что содержит вершину v. Мы можем посчитать это динамическое программирование при помощи простого dfs, для вершины v оно будет выглядеть следующим образом: dpv=av+∑to∈children(v)max(0,dpto).
  3.  
  4. Окей, мы где-то сохранили ответ для корня . Что дальше? Давайте попробуем сменить корень с вершины v на какую-то смежную с ней вершину to. Какие состояния динамического программирования изменятся? Только dpv и dpto. Сначала нам необходимо «удалить» ребенка to из поддерева вершины v: dpv=dpv−max(0,dpto). Затем нам необходимо «прицепить» вершину v и сделать ее сыном вершины to: dpto=dpto+max(0,dpv). Затем нам нужно запустить этот процесс рекурсивно из вершины to (сохранить ответ, переподвесить дерево и так далее), и когда он закончится, нам нужно будет «откатить» наши изменения. Теперь v опять является корнем и мы можем попробовать следующего сына v в качестве корня.
  5.  
  6. Асимптотика решения: O(n).
  7. //реализация
  8. #include <bits/stdc++.h>
  9.  
  10. using namespace std;
  11.  
  12. vector<int> a;
  13. vector<int> dp;
  14. vector<int> ans;
  15. vector<vector<int>> g;
  16.  
  17. void dfs(int v, int p = -1) {
  18. dp[v] = a[v];
  19. for (auto to : g[v]) {
  20. if (to == p) continue;
  21. dfs(to, v);
  22. dp[v] += max(dp[to], 0);
  23. }
  24. }
  25.  
  26. void dfs2(int v, int p = -1) {
  27. ans[v] = dp[v];
  28. for (auto to : g[v]) {
  29. if (to == p) continue;
  30. dp[v] -= max(0, dp[to]);
  31. dp[to] += max(0, dp[v]);
  32. dfs2(to, v);
  33. dp[to] -= max(0, dp[v]);
  34. dp[v] += max(0, dp[to]);
  35. }
  36. }
  37.  
  38. int main() {
  39. #ifdef _DEBUG
  40. freopen("input.txt", "r", stdin);
  41. // freopen("output.txt", "w", stdout);
  42. #endif
  43.  
  44. int n;
  45. cin >> n;
  46. a = dp = ans = vector<int>(n);
  47. g = vector<vector<int>>(n);
  48. for (int i = 0; i < n; ++i) {
  49. cin >> a[i];
  50. if (a[i] == 0) a[i] = -1;
  51. }
  52. for (int i = 0; i < n - 1; ++i) {
  53. int x, y;
  54. cin >> x >> y;
  55. --x, --y;
  56. g[x].push_back(y);
  57. g[y].push_back(x);
  58. }
  59.  
  60. dfs(0);
  61. dfs2(0);
  62. for (auto it : ans) cout << it << " ";
  63. cout << endl;
  64.  
  65. return 0;
  66. }
Advertisement
Add Comment
Please, Sign In to add comment