Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#define _CRT_SECURE_NO_WARNINGS
- #pragma comment(linker, "/STACK:16777216")
- #include <iostream>
- #include <cstdio>
- #include <vector>
- #include <cmath>
- #include <string>
- #include <algorithm>
- #include <string>
- #include <deque>
- #include <iomanip>
- #include <cstddef>
- #include <queue>
- #include <set>
- using namespace std;
- const int inf = 1000000000;
- vector <vector<pair<int, int> > > g;
- int used[50010], fin[50010], dist[50010];
- int timer = 0;
- vector<int> ord;
- int tree[10000000];
- int key[1000000];
- int unkey[1000000];
- void dfs(int v)
- {
- used[v] = 1;
- key[v] = timer++;
- unkey[key[v]] = v;
- if (fin[v] == -1)
- fin[v] = ord.size();
- ord.push_back(key[v]);
- for (int i = 0; i < g[v].size(); i++)
- if (!used[g[v][i].first])
- {
- dist[g[v][i].first] = dist[v] + g[v][i].second;
- dfs(g[v][i].first);
- ord.push_back(key[v]);
- }
- return;
- }
- void inc(int v, int l, int r, int k)
- {
- if (l + 1 == r)
- {
- tree[v] = ord[k];
- return;
- }
- int m = (l + r) / 2;
- if (k < m)
- inc(2 * v + 1, l, m, k);
- else
- if (k >= m)
- inc(2 * v + 2, m, r, k);
- tree[v] = min(tree[2 * v + 1], tree[2 * v + 2]);
- return;
- }
- int findmin(int v, int l, int r, int lv, int rv)
- {
- if (l == lv && r == rv)
- return tree[v];
- int m = (l + r) / 2;
- if (rv <= m)
- return findmin(2 * v + 1, l, m, lv, rv);
- else
- if (lv >= m)
- return findmin(2 * v + 2, m, r, lv, rv);
- return min(findmin(2 * v + 1, l, m, lv, m), findmin(2 * v + 2, m, r, m, rv));
- }
- int main()
- {
- ios_base::sync_with_stdio(0);
- //freopen("input.txt", "r", stdin);//freopen("output.txt", "w", stdout);
- // freopen("slalom.in", "r", stdin);freopen("slalom.out", "w", stdout);
- int n;
- cin >> n;
- g.resize(n);
- int u, v, d;
- for (int i = 0; i < n - 1; i++)
- {
- cin >> u >> v >> d;
- g[u].push_back(make_pair(v, d));
- g[v].push_back(make_pair(u, d));
- }
- fill(fin, fin + n, -1);
- fill(used, used + n, 0);
- dist[0] = 0;
- dfs(0);
- fill(tree, tree + 10000000, inf);
- for (int i = 0; i < ord.size(); i++)
- {
- inc(0, 0, ord.size(), i);
- }
- int m;
- cin >> m;
- int x, y;
- for (int i = 0; i < m; i++)
- {
- cin >> x >> y;
- if (fin[x] > fin[y])
- swap(x, y);
- int com = unkey[findmin(0, 0, ord.size(), fin[x], fin[y] + 1)];
- cout << dist[x] + dist[y] - 2 * dist[com] << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement