A weighted tree is given. You must find the distance between two given nodes.
Input
The first line contains the number of nodes of the tree
n (1 ≤ n ≤ 50000). The nodes are numbered from 0 to n – 1.Each of the next
n – 1 lines contains three integers u, v, w, which correspond to an edgewith weight
w (0 ≤ w ≤ 1000) connecting nodes u and v.The next line contains the number of queries
m (1 ≤ m ≤ 75000).In each of the next m lines there are two integers.
Output
For each query, output the distance between the nodes with the given numbers.
Sample
input | output |
---|---|
3 1 0 1 2 0 1 3 0 1 0 2 1 2 |
1 1 2 |
LCA向RMQ转换,注意询问时要判断区间下界是否小于上界,并且记录深度时不能带权。
Accode:
#pragma comment(linker, "/STACK:0x10000000")
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string>
#define RMQ_min(a, b) (D[a] < D[b] ? (a) : (b))
const int maxN = 50010;
const int maxORD = 100010;
struct Edge {int v, d; Edge *next;};
Edge *edge[maxN];
int D[maxORD], ord[maxORD], f[maxORD][20];
int fir[maxN], dist[maxN], Ind;
void Dfs(int u, int Last, int Dep)
{
ord[++Ind] = u; fir[u] = Ind; D[Ind] = Dep;
for (Edge *p = edge[u]; p; p = p -> next)
if (p -> v - Last)
{
dist[p -> v] = dist[u] + p -> d;
Dfs(p -> v, u, Dep + 1);
ord[++Ind] = u;
D[Ind] = Dep;
}
return;
}
inline void RMQ_set()
{
for (int i = 1; i < Ind + 1; ++i) f[i][0] = i;
for (int q = 0; 1 << q < Ind; ++q)
for (int i = 1; i + (1 << q) < Ind + 1; ++i)
f[i][q + 1] = RMQ_min(f[i][q], f[i + (1 << q)][q]);
return;
}
inline int RMQ(int L, int R)
{
if (L == R) return L;
if (L > R) std::swap(L, R); //
int q = 0; for (; 1 << q < R - L + 2; ++q); --q;
return RMQ_min(f[L][q], f[R - (1 << q) + 1][q]);
}
inline int getint()
{
int res = 0; char tmp;
while (!isdigit(tmp = getchar()));
do res = (res << 3) + (res << 1) + tmp - '0';
while (isdigit(tmp = getchar()));
return res;
}
inline void Ins(int u, int v, int d)
{
Edge *p = new Edge; p -> v = v;
p -> d = d; p -> next = edge[u];
edge[u] = p; return;
}
int main()
{
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
for (int n = getint(); --n;)
{
int u = getint(), v = getint(), d = getint();
Ins(u, v, d); Ins(v, u, d);
}
Dfs(0, -1, 0); RMQ_set();
for (int m = getint(); m; --m)
{
int u = getint(), v = getint();
printf("%d\n", dist[u] + dist[v] -
(dist[ord[RMQ(fir[u], fir[v])]] << 1));
}
return 0;
}
#undef RMQ_min