結果
問題 | No.898 tri-βutree |
ユーザー | ganariya |
提出日時 | 2019-10-05 12:01:07 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 848 ms / 4,000 ms |
コード長 | 5,087 bytes |
コンパイル時間 | 2,113 ms |
コンパイル使用メモリ | 158,640 KB |
実行使用メモリ | 39,108 KB |
最終ジャッジ日時 | 2024-11-08 22:51:44 |
合計ジャッジ時間 | 17,176 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 334 ms
39,108 KB |
testcase_01 | AC | 2 ms
5,248 KB |
testcase_02 | AC | 3 ms
5,248 KB |
testcase_03 | AC | 2 ms
5,248 KB |
testcase_04 | AC | 2 ms
5,248 KB |
testcase_05 | AC | 2 ms
5,248 KB |
testcase_06 | AC | 2 ms
5,248 KB |
testcase_07 | AC | 839 ms
36,220 KB |
testcase_08 | AC | 848 ms
36,224 KB |
testcase_09 | AC | 840 ms
36,224 KB |
testcase_10 | AC | 830 ms
36,224 KB |
testcase_11 | AC | 834 ms
36,096 KB |
testcase_12 | AC | 845 ms
36,224 KB |
testcase_13 | AC | 847 ms
36,224 KB |
testcase_14 | AC | 844 ms
36,224 KB |
testcase_15 | AC | 835 ms
36,224 KB |
testcase_16 | AC | 829 ms
36,096 KB |
testcase_17 | AC | 824 ms
36,224 KB |
testcase_18 | AC | 813 ms
36,224 KB |
testcase_19 | AC | 819 ms
36,188 KB |
testcase_20 | AC | 845 ms
36,224 KB |
testcase_21 | AC | 827 ms
36,224 KB |
ソースコード
//include //------------------------------------------ #include <vector> #include <list> #include <map> #include <unordered_map> #include <climits> #include <set> #include <unordered_set> #include <deque> #include <stack> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <cctype> #include <string> #include <cstring> #include <ctime> #include <queue> #include <random> #include <complex> #include <regex> #include <locale> #include <random> #include <type_traits> using namespace std; #define SHOW_VECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";} #define SHOW_MAP(v){std::cerr << #v << endl; for(const auto& xxx: v){std::cerr << xxx.first << " " << xxx.second << "\n";}} using LL = long long; //------------------------------------------ //------------------------------------------ template<class T> struct Edge { int from, to; T cost; Edge(int from, int to, T cost) : from(from), to(to), cost(cost) {} explicit operator int() const { return to; } }; template<class T> using Edges = vector<Edge<T>>; template<class T> using WeightedGraph = vector<Edges<T>>; using UnWeightedGraph = vector<vector<int>>; template<class T> using DistMatrix = vector<vector<T>>; struct GraphAdapter { template<class T> static UnWeightedGraph to_unweighted_graph(const WeightedGraph<T> &origin) { int V = origin.size(); UnWeightedGraph graph(V); for (int i = 0; i < V; i++) for (auto &e: origin[i]) graph[i].push_back((int) e); return graph; } static WeightedGraph<int> to_weighted_graph(const UnWeightedGraph &origin) { int V = origin.size(); WeightedGraph<int> graph(V); for (int i = 0; i < V; i++) for (auto to: origin[i]) graph[i].push_back({i, to, 1}); return graph; } }; struct Doubling { const long long LOG; const int N; vector<vector<int>> nexted; Doubling(int N, long long log = 60) : N(N), LOG(log) { nexted.assign(LOG + 1, vector<int>(N + 1, -1)); } inline void set_init_next(const int v, const int x) { nexted[0][v] = x; } void build() { for (int k = 0; k < LOG; k++) { for (int v = 0; v < N; v++) { if (nexted[k][v] == -1) nexted[k + 1][v] = -1; else nexted[k + 1][v] = nexted[k][nexted[k][v]]; } } } inline int query(int v, long long p) { for (long long i = LOG; i >= 0; i--) { if (v < 0) return -1; if (p & (1LL << i)) { v = nexted[i][v]; } } return v; } }; template<typename T> class LowestCommonAncestor { private: const long long LOG; const int N; const WeightedGraph<T> &graph; vector<int> depth; vector<T> dist; vector<vector<int>> nexted; public: LowestCommonAncestor(const WeightedGraph<T> &graph, const long long LOG = 60) : graph(graph), LOG(LOG), N(graph.size()), depth(N, -1), dist(N, numeric_limits<T>::max()) { nexted.assign(LOG + 1, vector<int>(N, -1)); } void dfs(int v, int p, int d, long long sum) { depth[v] = d; dist[v] = sum; nexted[0][v] = p; for (auto e: graph[v]) { int to = e.to; long long cost = e.cost; if (to != p) { dfs(to, v, d + 1, sum + cost); } } } void build(int s) { dfs(s, -1, 0, 0); for (int k = 0; k < LOG; k++) { for (int v = 0; v < N; v++) { if (nexted[k][v] == -1) nexted[k + 1][v] = -1; else nexted[k + 1][v] = nexted[k][nexted[k][v]]; } } } int lca(int u, int v) { if (depth[u] > depth[v]) swap(u, v); for (long long i = LOG - 1; i >= 0; i--) { if ((depth[v] - depth[u]) & (1LL << i)) { v = nexted[i][v]; } } if (u == v)return u; for (long long i = LOG - 1; i >= 0; i--) { if (nexted[i][u] != nexted[i][v]) { u = nexted[i][u]; v = nexted[i][v]; } } return nexted[0][u]; } T get_distance(int u, int v) { T sum = dist[u] + dist[v] - 2 * dist[lca(u, v)]; return sum; } }; int main() { int N; cin >> N; WeightedGraph<long long> graph(N); for (int i = 0; i < N - 1; i++) { int s, t, w; cin >> s >> t >> w; graph[s].push_back({s, t, w}); graph[t].push_back({t, s, w}); } LowestCommonAncestor<long long> LCA(graph); LCA.build(0); int Q; cin >> Q; while (Q--) { int x, y, z; cin >>x >> y >> z; long long ans = LCA.get_distance(x, y) + LCA.get_distance(y, z) + LCA.get_distance(z, x); cout << ans/2 << endl; } return 0; }