简述题意,给你一课最小支撑树,对每个询问,在原有的路径上增加x-y,问a-b是否有路径长度为k的路,每条路每个点可以重复使用
由于是最小支撑树,我们可以用LCA来快速判断每个点之间的距离,那么现在就要判断情况,假设从原有的路上,a-b的距离为d,d=k时显然成立,当d<k时,若(d-k)%2=0也成立,因为若其是2的倍数,他可以轮流进入b与b的前驱,最后停在b上,那么我们如何判断新加的边的,距离的判定和前者一样,但是距离的大小变化了,设(x,y)表示x到y的最短路径,则从a到b就有三种情况
1.(a,b) 该情况已经讨论过
2.(a,x)+(b,y)+1,意思从a到x,x到y的路径长度为1,y再到b
3.(a,y)+(b,x)+1,同理
三种情况下的距离判断都一样,具体上代码看一下就懂了
#include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&(-x)) typedef long long LL; const int maxm = 1e5+5; struct Node { int v, nex; } edges[maxm<<1]; int head[maxm<<1], edgecnt, grand[maxm][21], depth[maxm], limit; void addedge(int u, int v) { edges[++edgecnt] = {v, head[u]}; head[u] = edgecnt; } void dfs(int u, int fa) { depth[u] = depth[fa] + 1; grand[u][0] = fa; for(int i = 1; i <= limit; ++i) grand[u][i] = grand[grand[u][i-1]][i-1]; for(int i = head[u]; i; i = edges[i].nex) { int v = edges[i].v; if(v != fa) dfs(v, u); } } int lca(int a, int b) { if(a == b) return a; if(depth[a] > depth[b]) swap(a, b); for(int i = limit; i >= 0; i--) if(depth[a] <= depth[b] - (1<<i)) b = grand[b][i]; if(a == b) return a; for(int i = limit; i >= 0; --i) { if(grand[a][i] == grand[b][i]) continue; else { a = grand[a][i], b = grand[b][i]; } } return grand[a][0]; } int getdist(int a, int b) { int c = lca(a, b); return depth[a] + depth[b] - 2*depth[c]; } void run_case() { int n; cin >> n; limit = floor(log(n+0.0) / log(2.0)) + 1; int u, v; for(int i = 0; i < n-1; ++i) { cin >> u >> v; addedge(u, v), addedge(v, u); } dfs(1, 0); int q; cin >> q; int a, b, x, y, k; while(q--) { cin >> x >> y >> a >> b >> k; int dist = getdist(a, b); bool flag = false; if(dist <= k && (k-dist)%2==0) flag = true; dist = getdist(a, x) + getdist(b, y) + 1; if(dist <= k && (k-dist)%2==0) flag = true; dist = getdist(a, y) + getdist(b, x) + 1; if(dist <= k && (k-dist)%2==0) flag = true; if(flag) cout << "YES "; else cout << "NO "; } } int main() { ios::sync_with_stdio(false), cin.tie(0); //cout.setf(ios_base::showpoint);cout.precision(10); //int t; cin >> t; //while(t--) run_case(); cout.flush(); return 0; }