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
| #include <bits/stdc++.h>
using namespace std; #define fast \ ios_base::sync_with_stdio(false); \ cin.tie(NULL); const int N = 1e5 + 10; const int M = 1e6 + 10; const int INF = 0x3f3f3f3f; const long long LINF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-3; int tree[M][2]; int idx = 0; struct node{ int u,v,next; long long w; }a[M]; int f[N],cnt; void add(int u,int v,int w){ a[++cnt].v = v; a[cnt].w = w; a[cnt].next = f[u]; f[u] = cnt; } int n, m; int father[N][30], dep[N]; void build(int u, int fa, int deep){ if(u > n) return; father[u][0] = fa; dep[u] = deep; build(u << 1, u, deep + 1); build(u << 1 | 1, u, deep + 1); } int lg = 0; int lca(int x, int y) { if(dep[x] < dep[y]) swap(x, y); for (int i = lg; i >= 0; i--) { if(dep[father[x][i]] >= dep[y]) x = father[x][i]; } if(x == y) return x; for (int i = lg; i >= 0; i--) { if(father[x][i] != father[y][i]){ x = father[x][i]; y = father[y][i]; } } return father[x][0]; } unordered_map<int, unordered_map<int, long long>> dis; unordered_map<int, unordered_map<int, bool>> vis; void dijkstra(int s) { priority_queue<pair<long long, int>> q; q.push({0, s}); dis[s][s] = 0; while (!q.empty()) { int u = (q.top()).second; q.pop(); if(vis[s][u]) continue; vis[s][u] = 1; for (int i = f[u]; i; i = a[i].next) { int v = a[i].v; if (dep[v] <= dep[s]) continue; long long w = a[i].w; if (dis[s].count(v) == 0 || dis[s][v] > dis[s][u] + w) { dis[s][v] = dis[s][u] + w; q.push({-dis[s][v], v}); } } } } int main(){ cin >> n >> m; build(1, 0, 1); lg = (int)log(n) / log(2) + 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= lg; j++) { father[i][j] = father[father[i][j - 1]][j - 1]; } } int u, v, w; for (int i = 1; i <= m; i++){ scanf("%d%d%d", &u, &v, &w); add(v, u, w); add(u, v, w); } int q; cin >> q; while(q--) { int u, v; scanf("%d%d", &u, &v); int Lca = lca(u, v); long long Min = LINF; while(Lca) { if(dis[Lca].count(Lca) == 0) dijkstra(Lca); if(dis[Lca].count(u) && dis[Lca].count(v)) Min = min(Min, dis[Lca][u] + dis[Lca][v]); Lca = father[Lca][0]; } if(Min == LINF) printf("-1\n"); else printf("%lld\n", Min); } return 0; }
|