提交时间:2025-05-29 14:22:05

运行 ID: 193988

#include <iostream> #include <vector> #include <algorithm> using namespace std; const int MAXN = 505; vector<pair<int, int>> adj[MAXN]; // 邻接表存储树,{to, weight} int parent[MAXN][20]; // 倍增法求LCA int depth[MAXN]; int edge_weight[MAXN]; // 存储节点与其父节点之间的边权 // 预处理每个节点的父节点、深度和边权 void dfs(int u, int p, int d) { parent[u][0] = p; depth[u] = d; for (auto [v, w] : adj[u]) { if (v != p) { edge_weight[v] = w; dfs(v, u, d + 1); } } } // 预处理倍增数组 void preprocess_lca(int n) { for (int k = 1; k < 20; k++) { for (int u = 1; u <= n; u++) { if (parent[u][k - 1] != -1) { parent[u][k] = parent[parent[u][k - 1]][k - 1]; } else { parent[u][k] = -1; } } } } // 求最近公共祖先 int lca(int u, int v) { if (depth[u] < depth[v]) swap(u, v); // 调整到同一深度 for (int k = 19; k >= 0; k--) { if (depth[u] - (1 << k) >= depth[v]) { u = parent[u][k]; } } if (u == v) return u; // 一起向上跳 for (int k = 19; k >= 0; k--) { if (parent[u][k] != -1 && parent[u][k] != parent[v][k]) { u = parent[u][k]; v = parent[v][k]; } } return parent[u][0]; } // 获取u到v路径上的边权集合(去重且排序) vector<int> get_path_weights(int u, int v) { vector<int> path; int ancestor = lca(u, v); // 从u到ancestor while (u != ancestor) { path.push_back(edge_weight[u]); u = parent[u][0]; } // 从v到ancestor vector<int> temp; while (v != ancestor) { temp.push_back(edge_weight[v]); v = parent[v][0]; } // 合并路径 path.insert(path.end(), temp.rbegin(), temp.rend()); // 去重并排序 sort(path.begin(), path.end()); path.erase(unique(path.begin(), path.end()), path.end()); return path; } int main() { int N; cin >> N; for (int i = 0; i < N - 1; i++) { int u, v, w; cin >> u >> v >> w; adj[u].push_back({v, w}); adj[v].push_back({u, w}); } // 预处理 dfs(1, -1, 0); preprocess_lca(N); int M; cin >> M; for (int i = 0; i < M; i++) { int U, V, R; cin >> U >> V >> R; vector<int> path = get_path_weights(U, V); int count = 0; // 遍历所有可能的x值 for (int x = 1; x <= R; x++) { int sum = 0; // 统计路径中边权 >=x 的边数 for (int w : path) { if (w >= x) sum++; } // 如果边数为偶数,Bob必胜 if (sum % 2 == 0) count++; } cout << count << endl; } return 0; }