Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- using namespace std;
- int upper_log2(int n) {
- int t = 1;
- int ans = 0;
- while (t <= n) {
- t *= 2;
- ++ans;
- }
- return ans;
- }
- class Tree {
- public:
- Tree(vector<int> &a, vector<int> cost) : costs(cost) {
- graph.resize(a.size());
- parent.resize(a.size(), vector<int>(upper_log2(a.size())));
- sums.assign(a.size(), vector<int>(upper_log2(a.size()), 0));
- tin.resize(a.size());
- tout.resize(a.size());
- for (int i = 0; i < a.size(); ++i) {
- if (a[i] == -1) {
- root = i;
- } else {
- graph[a[i]].push_back(i);
- }
- }
- }
- bool Check(int parent, int child) {
- return tin[parent] <= tin[child] && tout[child] <= tout[parent];
- }
- int CheapestEdge(int a, int b) {
- int summ = 0;
- for (int i = parent[a].size() - 1; i >= 0; --i) {
- if (!Check(parent[a][i], b)) {
- summ += sums[a][i];
- a = parent[a][i];
- }
- }
- int summ2 = 0;
- for (int i = parent[b].size() - 1; i >= 0; --i) {
- if (!Check(parent[b][i], a)) {
- summ2 += sums[b][i];
- b = parent[b][i];
- }
- }
- // cout << a << ' ' << minims[a][0] << ' ' << b << ' ' << minims[b][0] << endl;
- if (Check(a, b)) {
- return summ2 + sums[b][0];
- }
- if (Check(b, a)) {
- summ + sums[a][0];
- }
- return summ + summ2 + sums[a][0] + sums[b][0];
- }
- void dfs() {
- return dfs(root, 0);
- }
- private:
- vector<vector<int>> graph;
- vector<vector<int>> parent;
- vector<vector<int>> sums;
- vector<int> costs;
- vector<int> tin;
- vector<int> tout;
- int time = 0;
- int root;
- void dfs(int n, int prev) {
- parent[n][0] = prev;
- sums[n][0] = costs[n];
- tin[n] = ++time;
- for (int i = 1; i < parent[n].size(); ++i) {
- parent[n][i] = parent[parent[n][i - 1]][i - 1];
- sums[n][i] = sums[n][i - 1] + sums[parent[n][i - 1]][i - 1];
- }
- for (auto neigh: graph[n]) {
- dfs(neigh, n);
- }
- tout[n] = ++time;
- }
- };
- int main() {
- int n;
- cin >> n;
- vector<int> vec(n);
- vector<int> cost(n);
- vec[0] = -1;
- cost[0] = 1e9;
- for (size_t i = 1; i < n; ++i) {
- cin >> vec[i] >> cost[i], --vec[i];
- }
- Tree tree(vec, cost);
- tree.dfs();
- int m;
- cin >> m;
- for (size_t i = 0; i < m; ++i) {
- int a, b;
- cin >> a >> b, --a, --b;
- cout << tree.CheapestEdge(a, b) << '\n';
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement