Advertisement
pasholnahuy

Сумма ребер на пути

Jun 12th, 2023
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.76 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4.  
  5. using namespace std;
  6.  
  7. int upper_log2(int n) {
  8. int t = 1;
  9. int ans = 0;
  10. while (t <= n) {
  11. t *= 2;
  12. ++ans;
  13. }
  14. return ans;
  15. }
  16.  
  17. class Tree {
  18. public:
  19. Tree(vector<int> &a, vector<int> cost) : costs(cost) {
  20. graph.resize(a.size());
  21. parent.resize(a.size(), vector<int>(upper_log2(a.size())));
  22. sums.assign(a.size(), vector<int>(upper_log2(a.size()), 0));
  23. tin.resize(a.size());
  24. tout.resize(a.size());
  25. for (int i = 0; i < a.size(); ++i) {
  26. if (a[i] == -1) {
  27. root = i;
  28. } else {
  29. graph[a[i]].push_back(i);
  30. }
  31. }
  32. }
  33.  
  34. bool Check(int parent, int child) {
  35. return tin[parent] <= tin[child] && tout[child] <= tout[parent];
  36. }
  37.  
  38. int CheapestEdge(int a, int b) {
  39. int summ = 0;
  40. for (int i = parent[a].size() - 1; i >= 0; --i) {
  41. if (!Check(parent[a][i], b)) {
  42. summ += sums[a][i];
  43. a = parent[a][i];
  44. }
  45. }
  46. int summ2 = 0;
  47. for (int i = parent[b].size() - 1; i >= 0; --i) {
  48. if (!Check(parent[b][i], a)) {
  49. summ2 += sums[b][i];
  50. b = parent[b][i];
  51. }
  52. }
  53. // cout << a << ' ' << minims[a][0] << ' ' << b << ' ' << minims[b][0] << endl;
  54. if (Check(a, b)) {
  55. return summ2 + sums[b][0];
  56. }
  57. if (Check(b, a)) {
  58. summ + sums[a][0];
  59. }
  60. return summ + summ2 + sums[a][0] + sums[b][0];
  61.  
  62. }
  63.  
  64. void dfs() {
  65. return dfs(root, 0);
  66. }
  67.  
  68. private:
  69. vector<vector<int>> graph;
  70. vector<vector<int>> parent;
  71. vector<vector<int>> sums;
  72. vector<int> costs;
  73. vector<int> tin;
  74. vector<int> tout;
  75. int time = 0;
  76. int root;
  77.  
  78. void dfs(int n, int prev) {
  79. parent[n][0] = prev;
  80. sums[n][0] = costs[n];
  81. tin[n] = ++time;
  82. for (int i = 1; i < parent[n].size(); ++i) {
  83. parent[n][i] = parent[parent[n][i - 1]][i - 1];
  84. sums[n][i] = sums[n][i - 1] + sums[parent[n][i - 1]][i - 1];
  85. }
  86. for (auto neigh: graph[n]) {
  87. dfs(neigh, n);
  88. }
  89. tout[n] = ++time;
  90. }
  91. };
  92.  
  93. int main() {
  94. int n;
  95. cin >> n;
  96. vector<int> vec(n);
  97. vector<int> cost(n);
  98. vec[0] = -1;
  99. cost[0] = 1e9;
  100. for (size_t i = 1; i < n; ++i) {
  101. cin >> vec[i] >> cost[i], --vec[i];
  102. }
  103. Tree tree(vec, cost);
  104. tree.dfs();
  105. int m;
  106. cin >> m;
  107. for (size_t i = 0; i < m; ++i) {
  108. int a, b;
  109. cin >> a >> b, --a, --b;
  110. cout << tree.CheapestEdge(a, b) << '\n';
  111. }
  112. return 0;
  113. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement