#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 2E5 + 10;
int n, m, x, y, z, kase;
struct Node
{
int to, val;
Node(int to = 0, int val = 0): to(to), val(val) {}
};
struct Ask
{
int u, v, lca;
Ask(int u = 0, int v = 0, int lca = 0): u(u), v(v), lca(lca) {}
};
vector<Ask>e;
vector<Node>g[maxn];
vector<int>query[maxn];
bool vis[maxn];
int fa[maxn], ance[maxn], dir[maxn];
void init()
{
memset(vis, 0, sizeof(vis));
for (int i = 0; i <= n; i++)
g[i].clear(), query[i].clear();
e.clear();
}
void Add_Node()
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
g[u].push_back(Node(v, w));
g[v].push_back(Node(u, w));
}
void Add_Ask(int u, int v)
{
e.push_back(Ask(u, v, -1));
e.push_back(Ask(v, u, -1));
int len = e.size() - 1;
query[v].push_back(len);
query[u].push_back(len - 1);
}
void Add_Ask()
{
scanf("%d%d%d", &x, &y, &z);
Add_Ask(x, y); Add_Ask(x, z); Add_Ask(y, z);
}
int Find(int x)
{
return x == fa[x] ? x : fa[x] = Find(fa[x]);
}
void Tarjan(int u, int val)
{
vis[u] = true;
ance[u] = fa[u] = u;
dir[u] = val;
for (int i = 0; i < g[u].size(); i++)
if (!vis[g[u][i].to])
{
Node tmp = g[u][i];
Tarjan(tmp.to, val + tmp.val);
fa[tmp.to] = u;
}
for (int i = 0; i < query[u].size(); i++)
{
int num = query[u][i];
Ask& tmp = e[num];
if (vis[tmp.v])
tmp.lca = e[num ^ 1].lca = ance[Find(tmp.v)];
}
}
int main(int argc, char const *argv[])
{
while (~scanf("%d", &n))
{
init();
for (int i = 1; i < n; i++)
Add_Node();
scanf("%d", &m);
for (int i = 0; i < m; i++)
Add_Ask();
Tarjan(0, 0);
if (kase++) printf("\n");
int ans = 0;
for (int i = 0; i < 3 * m; i++)
{
ans += (dir[e[i * 2].u] + dir[e[i * 2].v] - 2 * dir[e[i * 2].lca]);
if (i % 3 == 2) printf("%d\n", ans / 2), ans = 0;
}
}
return 0;
}
给出一个图,求三点的连起来的距离。
Tarjan离线算法,分别求出三点中任意两点的距离 / 2