给出一棵树,询问在增加一条边的情况下,是否存在a->b走过的边权和正好为k(可重复经过某边)。
ps:漏了两个判断条件,真惨。
首先可以重复经过某些顶点和边,假设a到b的距离是dis,那么dis + 2, dis + 4,
dis + 6......这些都是满足的a到达b,现在只需要判断奇偶性。如果dis是奇数,那么k
必须是大于dis的奇数才行;偶数同理。a到b有三条路径d,
a -> b,
a -> x - > y - > b,
a- > y - > x -> b.
然后记录dis与k的奇偶相同且最小的距离,判断是否小于等于k即可。
时间复杂度:O(m * logn)
#include
#include
#include
#include
#include
using namespace std;
#define IOS ios::sync_with_stdio(false)
const int maxn = 2e5 + 100;
const int inf = 0x3f3f3f3f;
struct Edge{
int to, next, w;
}edge[maxn];
int dis[maxn], fa[21][maxn], head[maxn], deep[maxn], cnt;
void init(){
memset(dis, 0, sizeof(dis));
memset(fa, 0, sizeof(fa));
memset(head, -1, sizeof(head));
memset(deep, 0, sizeof(deep));
cnt = 0;
}
void add(int u, int v, int w){
edge[cnt].to = v;
edge[cnt].w = w;
edge[cnt].next = head[u];
head[u] = cnt++;
}
void dfs(int u, int fno){
for (int i = 1; i <=20; ++i){
fa[i][u] = fa[i - 1][fa[i - 1][u]];
}
for (int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if (v == fno) continue;
dis[v] = dis[u] + edge[i].w;
fa[0][v] = u;
deep[v] = deep[u] + 1;
dfs(v, u);
}
}
int LCA(int x, int y){
if (deep[x] < deep[y]){
swap(x, y);
}
for (int i = 20; i >= 0; --i){
if (deep[x] -deep[y] >> i){
x = fa[i][x];
}
}
if (x == y) return x;
for (int i = 20; i >= 0; --i){
if (fa[i][x] != fa[i][y]){
x = fa[i][x];
y = fa[i][y];
}
}
return fa[0][x];
}
int distance(int x, int y){
return dis[x] + dis[y] - 2 * dis[LCA(x, y)];
}
void solve(){
int n, u, v;
scanf("%d", &n);
init();
for (int i = 1; i < n; ++i){
scanf("%d%d", &u, &v);
add(u, v, 1);
add(v, u, 1);
}
dfs(1, 0);
int m, x, y, a, b, k;
scanf("%d", &m);
while (m--){
scanf("%d%d%d%d%d", &x, &y, &a, &b, &k);
int disab1 = distance(a, b);
int disab2 = distance(a, x) + distance(b, y) + 1;
int disab3 = distance(a, y) + distance(b, x) + 1;
int flag = inf;
//记录a到b的距离,并且判断disab和k的奇偶相同,如果相同记录ab最短路径是否小于等于k即可。
if (disab1 % 2 == k % 2){
flag = min(flag, disab1);
}
if (disab2 % 2 == k % 2){
flag = min(flag, disab2);
}
if (disab3 % 2 == k % 2){
flag = min(flag, disab3);
}
if (flag <= k){
puts("YES");
} else {
puts("NO");
}
}
}
int main(){
solve();
return 0;
}