結果
問題 | No.1600 Many Shortest Path Problems |
ユーザー | SSRS |
提出日時 | 2021-07-09 22:25:34 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 5,165 bytes |
コンパイル時間 | 2,474 ms |
コンパイル使用メモリ | 196,712 KB |
実行使用メモリ | 41,048 KB |
最終ジャッジ日時 | 2024-07-01 17:04:10 |
合計ジャッジ時間 | 34,521 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
32,640 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 3 ms
5,376 KB |
testcase_04 | AC | 2,779 ms
40,960 KB |
testcase_05 | AC | 2,465 ms
40,960 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 2 ms
5,376 KB |
testcase_08 | AC | 2 ms
5,376 KB |
testcase_09 | AC | 2 ms
5,376 KB |
testcase_10 | AC | 667 ms
6,528 KB |
testcase_11 | AC | 1,179 ms
8,192 KB |
testcase_12 | AC | 1,945 ms
16,768 KB |
testcase_13 | AC | 2,347 ms
31,104 KB |
testcase_14 | AC | 2,317 ms
41,048 KB |
testcase_15 | AC | 2 ms
5,376 KB |
testcase_16 | AC | 2 ms
5,376 KB |
testcase_17 | AC | 2,094 ms
23,680 KB |
testcase_18 | AC | 2,027 ms
40,960 KB |
testcase_19 | AC | 2 ms
5,376 KB |
testcase_20 | AC | 2 ms
5,376 KB |
testcase_21 | AC | 2,119 ms
23,680 KB |
testcase_22 | AC | 2 ms
5,376 KB |
testcase_23 | AC | 2 ms
5,376 KB |
testcase_24 | AC | 2,160 ms
40,960 KB |
testcase_25 | AC | 2 ms
5,376 KB |
testcase_26 | AC | 2 ms
5,376 KB |
testcase_27 | AC | 2 ms
5,376 KB |
testcase_28 | AC | 2 ms
5,376 KB |
testcase_29 | AC | 682 ms
29,056 KB |
testcase_30 | TLE | - |
testcase_31 | -- | - |
testcase_32 | -- | - |
testcase_33 | -- | - |
testcase_34 | -- | - |
testcase_35 | -- | - |
testcase_36 | -- | - |
testcase_37 | -- | - |
testcase_38 | -- | - |
testcase_39 | -- | - |
testcase_40 | -- | - |
testcase_41 | -- | - |
testcase_42 | -- | - |
testcase_43 | -- | - |
testcase_44 | -- | - |
testcase_45 | -- | - |
testcase_46 | -- | - |
testcase_47 | -- | - |
testcase_48 | -- | - |
testcase_49 | -- | - |
testcase_50 | -- | - |
testcase_51 | -- | - |
testcase_52 | -- | - |
testcase_53 | -- | - |
ソースコード
#include <bits/stdc++.h> using namespace std; const int LOG = 18; const int INF = 10000000; const long long MOD = 1000000007; struct unionfind{ vector<int> p; unionfind(int N){ p = vector<int>(N, -1); } int root(int x){ if (p[x] < 0){ return x; } else { p[x] = root(p[x]); return p[x]; } } bool same(int x, int y){ return root(x) == root(y); } void unite(int x, int y){ x = root(x); y = root(y); if (x != y){ if (p[x] < p[y]){ swap(x, y); } p[y] += p[x]; p[x] = y; } } }; struct dual_segment_tree{ int N; vector<int> ST; dual_segment_tree(){ } dual_segment_tree(int N2){ N = 1; while (N < N2){ N *= 2; } ST = vector<int>(N * 2 - 1, INF); } int operator [](int k){ k += N - 1; int ans = ST[k]; while (k > 0){ k = (k - 1) / 2; ans = min(ans, ST[k]); } return ans; } void range_chmin(int L, int R, int x, int i, int l, int r){ if (r <= L || R <= l){ return; } else if (L <= l && r <= R){ ST[i] = min(ST[i], x); } else { int m = (l + r) / 2; range_chmin(L, R, x, i * 2 + 1, l, m); range_chmin(L, R, x, i * 2 + 2, m, r); } } void range_chmin(int L, int R, int x){ range_chmin(L, R, x, 0, 0, N); } }; struct heavy_light_decomposition{ vector<int> p, sz, in, next; vector<int> d1; vector<long long> d2; dual_segment_tree ST; heavy_light_decomposition(vector<int> &p, vector<vector<pair<long long, int>>> &c): p(p){ int N = p.size(); sz = vector<int>(N, 0); d1 = vector<int>(N, 0); d2 = vector<long long>(N, 0); dfs1(c); in = vector<int>(N, 0); next = vector<int>(N, 0); int t = 0; dfs2(c, t); ST = dual_segment_tree(N); } void dfs1(vector<vector<pair<long long, int>>> &c, int v = 0){ sz[v] = 1; for (auto &P : c[v]){ int w = P.second; d1[w] = d1[v] + 1; d2[w] = d2[v] + P.first; dfs1(c, w); if (sz[w] > sz[c[v][0].second]){ swap(P, c[v][0]); } } } void dfs2(vector<vector<pair<long long, int>>> &c, int &t, int v = 0){ in[v] = t; t++; for (auto P : c[v]){ int w = P.second; if (P == c[v][0]){ next[w] = next[v]; } else { next[w] = w; } dfs2(c, t, w); } } int lca(int x, int y){ while (true){ if (in[x] > in[y]){ swap(x, y); } if (next[x] == next[y]){ return x; } y = p[next[y]]; } } int dist1(int x, int y){ return d1[x] + d1[y] - 2 * d1[lca(x, y)]; } long long dist2(int x, int y){ return d2[x] + d2[y] - 2 * d2[lca(x, y)]; } int operator [](int v){ return ST[in[v]]; } void path_chmin(int u, int v, int x){ int w = lca(u, v); while (next[u] != next[w]){ ST.range_chmin(in[next[u]], in[u] + 1, x); u = p[next[u]]; } ST.range_chmin(in[w] + 1, in[u] + 1, x); while (next[v] != next[w]){ ST.range_chmin(in[next[v]], in[v] + 1, x); v = p[next[v]]; } ST.range_chmin(in[w] + 1, in[v] + 1, x); } }; int main(){ int N, M; cin >> N >> M; vector<pair<int, int>> E(M); for (int i = 0; i < M; i++){ int A, B; cin >> A >> B; A--; B--; E[i] = make_pair(A, B); } vector<long long> cost(M); cost[0] = 2; for (int i = 1; i < M; i++){ cost[i] = cost[i - 1] * 2 % MOD; } unionfind UF(N); vector<bool> span(M, false); vector<vector<pair<long long, int>>> E2(N); for (int i = 0; i < M; i++){ int A = E[i].first; int B = E[i].second; if (!UF.same(A, B)){ span[i] = true; UF.unite(A, B); E2[A].push_back(make_pair(cost[i], B)); E2[B].push_back(make_pair(cost[i], A)); } } vector<int> p(N, -1); vector<vector<pair<long long, int>>> c(N); vector<int> d(N, 0); queue<int> q; q.push(0); while (!q.empty()){ int v = q.front(); q.pop(); for (auto P : E2[v]){ int w = P.second; if (w != p[v]){ p[w] = v; c[v].push_back(P); d[w] = d[v] + 1; q.push(w); } } } heavy_light_decomposition T(p, c); for (int i = 0; i < M; i++){ if (!span[i]){ int A = E[i].first; int B = E[i].second; T.path_chmin(A, B, i); } } int Q; cin >> Q; for (int i = 0; i < Q; i++){ int x, y, z; cin >> x >> y >> z; x--; y--; z--; int a = E[z].first; int b = E[z].second; if (!span[z]){ cout << T.dist2(x, y) % MOD << endl; } else { int d1 = T.dist1(x, a) + T.dist1(b, y); int d2 = T.dist1(x, b) + T.dist1(a, y); int d3 = T.dist1(x, y); if (d1 + 1 != d3 && d2 + 1 != d3){ cout << T.dist2(x, y) % MOD << endl; } else { if (b == p[a]){ swap(a, b); } int mn = T[b]; if (mn == INF){ cout << -1 << endl; } else { int c = E[mn].first; int d = E[mn].second; long long ans1 = T.dist2(x, c) + cost[mn] + T.dist2(d, y); long long ans2 = T.dist2(x, d) + cost[mn] + T.dist2(c, y); cout << min(ans1, ans2) % MOD << endl; } } } } }