結果
問題 |
No.1442 I-wate Shortest Path Problem
|
ユーザー |
![]() |
提出日時 | 2025-03-31 17:54:03 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,327 bytes |
コンパイル時間 | 6,974 ms |
コンパイル使用メモリ | 228,152 KB |
実行使用メモリ | 39,476 KB |
最終ジャッジ日時 | 2025-03-31 17:55:45 |
合計ジャッジ時間 | 15,853 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 12 WA * 13 |
ソースコード
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll INF = 1e18; struct LCA { vector<int> depth; vector<vector<int>> parent; vector<vector<ll>> dist; int max_log; LCA(int n, const vector<vector<pair<int, ll>>> &tree) { max_log = 0; while ((1 << max_log) < n) max_log++; depth.resize(n); parent.assign(max_log, vector<int>(n, -1)); dist.assign(max_log, vector<ll>(n, 0)); queue<int> q; q.push(0); depth[0] = 0; parent[0][0] = -1; while (!q.empty()) { int u = q.front(); q.pop(); for (auto &[v, c] : tree[u]) { if (parent[0][v] == -1 && v != 0) { depth[v] = depth[u] + 1; parent[0][v] = u; dist[0][v] = c; q.push(v); } } } for (int k = 1; k < max_log; k++) { for (int v = 0; v < n; v++) { if (parent[k-1][v] != -1) { parent[k][v] = parent[k-1][parent[k-1][v]]; dist[k][v] = dist[k-1][v] + dist[k-1][parent[k-1][v]]; } } } } pair<int, ll> lca(int u, int v) { ll sum = 0; if (depth[u] < depth[v]) swap(u, v); for (int k = max_log-1; k >= 0; k--) { if (depth[u] - (1 << k) >= depth[v]) { sum += dist[k][u]; u = parent[k][u]; } } if (u == v) return {u, sum}; for (int k = max_log-1; k >= 0; k--) { if (parent[k][u] != -1 && parent[k][u] != parent[k][v]) { sum += dist[k][u] + dist[k][v]; u = parent[k][u]; v = parent[k][v]; } } sum += dist[0][u] + dist[0][v]; return {parent[0][u], sum}; } ll distance(int u, int v) { auto [ancestor, d] = lca(u, v); return d; } }; vector<ll> dijkstra_airline(const vector<vector<pair<int, ll>>> &tree, const vector<int> &sources) { int n = tree.size(); vector<ll> dist(n, INF); priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq; for (int s : sources) { dist[s] = 0; pq.emplace(0, s); } while (!pq.empty()) { auto [d, u] = pq.top(); pq.pop(); if (d > dist[u]) continue; for (auto [v, c] : tree[u]) { if (dist[v] > dist[u] + c) { dist[v] = dist[u] + c; pq.emplace(dist[v], v); } } } return dist; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, K; cin >> N >> K; vector<vector<pair<int, ll>>> tree(N); for (int i = 0; i < N-1; i++) { int a, b, c; cin >> a >> b >> c; a--; b--; tree[a].emplace_back(b, c); tree[b].emplace_back(a, c); } LCA lca(N, tree); vector<int> P(K); vector<vector<ll>> min_dist(K); for (int i = 0; i < K; i++) { int M, p; cin >> M >> p; P[i] = p; vector<int> sources; for (int j = 0; j < M; j++) { int x; cin >> x; x--; sources.push_back(x); } min_dist[i] = dijkstra_airline(tree, sources); } vector<ll> sum_P(1 << K, 0); for (int mask = 1; mask < (1 << K); mask++) { for (int i = 0; i < K; i++) { if (mask & (1 << i)) { sum_P[mask] = sum_P[mask ^ (1 << i)] + P[i]; break; } } } int Q; cin >> Q; vector<int> sorted_a_order(K), sorted_b_order(K); while (Q--) { int u, v; cin >> u >> v; u--; v--; ll rail_cost = lca.distance(u, v); if (K == 0) { cout << rail_cost << '\n'; continue; } vector<ll> a(K), b(K); for (int i = 0; i < K; i++) { a[i] = min_dist[i][u]; b[i] = min_dist[i][v]; } iota(sorted_a_order.begin(), sorted_a_order.end(), 0); sort(sorted_a_order.begin(), sorted_a_order.end(), [&a](int i, int j) { return a[i] < a[j]; }); iota(sorted_b_order.begin(), sorted_b_order.end(), 0); sort(sorted_b_order.begin(), sorted_b_order.end(), [&b](int i, int j) { return b[i] < b[j]; }); ll min_candidate = INF; for (int mask = 1; mask < (1 << K); mask++) { ll sum_p = sum_P[mask]; ll current_a = INF; for (int i : sorted_a_order) { if (mask & (1 << i)) { current_a = a[i]; break; } } ll current_b = INF; for (int i : sorted_b_order) { if (mask & (1 << i)) { current_b = b[i]; break; } } if (current_a == INF || current_b == INF) continue; ll candidate = sum_p + current_a + current_b; if (candidate < min_candidate) { min_candidate = candidate; } } ll answer = min(rail_cost, min_candidate); cout << answer << '\n'; } return 0; }