1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include<algorithm> #include<cstdio> #include<cstring>
struct IO { template<typename T> inline IO operator>>(T &n) { n=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c>='0'&&c<='9') n=(n<<3)+(n<<1)+(c^48),c=getchar(); return *this; } } cin;
constexpr int MX = 14;
char op[5]; int T, N, u, v, w, tot, head[10003], dep[10003], wn[10003], fa[10003][15];
struct Edge { int nxt, to, w; } e[20003];
inline void addEdge(int u, int v, int w) { e[++tot] = {head[u], v, w}; head[u] = tot; }
void dfs(int u, int f) { dep[u] = dep[f] + 1; fa[u][0] = f; for (int i = 1; (1 << i) <= dep[u]; ++i) fa[u][i] = fa[fa[u][i - 1]][i - 1]; for (int i = head[u], v; i; i = e[i].nxt) { if ((v = e[i].to) == f) continue; wn[v] = wn[u] + e[i].w; dfs(v, u); } }
int Lca(int u, int v) { if (dep[u] < dep[v]) std::swap(u, v); for (int i = MX; i >= 0; --i) if (dep[v] <= dep[u] - (1 << i)) u = fa[u][i]; if (u == v) return u; for (int i = MX; i >= 0; --i) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; }
int queryt(int u, int v, int k) { int f = Lca(u, v); if (dep[u] - dep[f] + 1 <= k) { k = dep[u] + dep[v] - (dep[f] << 1) + 2 - k; u = v; } for (int i = MX; i >= 0; --i) if (k >= (1 << i) + 1) { u = fa[u][i]; k -= (1 << i); } return u; }
void init() { tot = wn[1] = 0; memset(fa, 0, sizeof fa); memset(head, 0, sizeof head); cin >> N; for (int i = 1; i < N; ++i) { cin >> u >> v >> w; addEdge(u, v, w); addEdge(v, u, w); } }
int main() { for (cin >> T; T; --T) { init(); dfs(1, 0); while(1) { scanf("%s", op); if (op[1] == 'O') break; if (op[1] == 'I') { cin >> u >> v; printf("%d\n", wn[u] + wn[v] - (wn[Lca(u, v)] << 1)); } else { cin >> u >> v >> w; printf("%d\n", queryt(u, v, w)); } } } return 0; }
|