小A的最短路
题目地址:
基本思路:
今天的题目比较套路,
首先这个图实际上是一棵树,所以我们可以直接用求树上距离,
然后对于有缆车的两个节点,假设为,
那么对于每次查询两点的最短路,
我们只要用, 来更新原本的最短路 就行了。
参考代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; #define IO std::ios::sync_with_stdio(false); cin.tie(0) #define int long long #define rep(i, l, r) for (int i = l; i <= r; i++) #define per(i, l, r) for (int i = l; i >= r; i--) #define mset(s, _) memset(s, _, sizeof(s)) #define pb push_back #define pii pair <int, int> #define mp(a, b) make_pair(a, b) #define INF (int)1e18 inline int read() { int x = 0, neg = 1; char op = getchar(); while (!isdigit(op)) { if (op == '-') neg = -1; op = getchar(); } while (isdigit(op)) { x = 10 * x + op - '0'; op = getchar(); } return neg * x; } inline void print(int x) { if (x < 0) { putchar('-'); x = -x; } if (x >= 10) print(x / 10); putchar(x % 10 + '0'); } const int maxn = (int)3e5 + 10; int n,q; struct edge { int next, v; }edges[maxn*2]; int cnt; int head[maxn]; void init() { memset(head, -1, sizeof(head)); cnt = 0; } void add_edge(int u,int v) { edges[cnt].next = head[u]; edges[cnt].v = v; head[u] = cnt++; } int dep[maxn]; int f[maxn][21]; void dfs(int u,int fa) { dep[u] = dep[fa] + 1; for (int i = 0; i <= 19; i++) f[u][i + 1] = f[f[u][i]][i]; for (int i = head[u]; i != -1; i = edges[i].next) { int v = edges[i].v; if (v == fa) continue; f[v][0] = u; dfs(v, u); } } int lca(int x,int y) { if (dep[x] < dep[y]) swap(x, y); for (int i = 20; i >= 0; i--) { if (dep[f[x][i]] >= dep[y]) x = f[x][i]; if (x == y) return x; } for (int i = 20; i >= 0; i--) { if (f[x][i] != f[y][i]) { x = f[x][i]; y = f[y][i]; } } return f[x][0]; } int dist(int a,int b){ return dep[a] + dep[b] - 2 * dep[lca(a, b)]; } int x,y; signed main() { IO; n = read(); init(); rep(i, 1, n - 1) { int u = read(), v = read(); add_edge(u, v); add_edge(v, u); } x = read(), y = read(); dfs(1, 0); q = read(); while (q--) { int u = read(), v = read(); int dis = dist(u, v); int t1 = dist(u, x), t2 = dist(v, y); dis = min(dis, t1 + t2); t1 = dist(u, y), t2 = dist(v, x); dis = min(dis, t1 + t2); cout << dis << '\n'; } return 0; }