由于一条路径可以包含一条边多次
那么从每个结点出发
但是
AC代码
#include <iostream>
#include <vector>
#define maxn 100005
using namespace std;
void tarjan(int u);
void merge(int u, int v);
int find(int u);
void add_query(int x, int y, int num);
struct query {
int to, num;
query(int _to, int _num) {
this->to = _to;
this->num = _num;
}
//num: index in Q[]
};
vector<query> Gq[maxn];//每个顶点的请求列表
vector<int> G[maxn];//原图
int Q[5 * maxn];
//Q[5 * i]: ab[i]
//Q[5 * i + 1]: xa[i]
//Q[5 * i + 2]: yb[i]
//Q[5 * i + 3]: xb[i]
//Q[5 * i + 4]: ya[i]
int deep[maxn];
int k[maxn];
int fa[maxn];
bool vis[maxn];
int main() {
cin.tie(0);
cout.tie(0);
cin.sync_with_stdio(0);
int n, u, v;
cin >> n;
for(int i = 1; i < n; i++) {
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
fa[i] = i;
}
fa[n] = n;
int q, x, y, a, b;
cin >> q;
for(int i = 0; i < q; i++) {
cin >> x >> y >> a >> b >> (k[i]);
add_query(a, b, 5 * i);
add_query(x, a, 5 * i + 1);
add_query(y, b, 5 * i + 2);
add_query(x, b, 5 * i + 3);
add_query(y, a, 5 * i + 4);
}
tarjan(1);
bool ok;
for(int i = 0; i < q; i++) {
ok = false;
int ab = Q[5 * i], xa = Q[5 * i + 1], yb = Q[5 * i + 2], xb = Q[5 * i + 3], ya = Q[5 * i + 4];
if(((k[i] + ab) & 1) == 0 && k[i] >= ab) {
ok = true;
} else if(((k[i] + xa + yb + 1) & 1) == 0 && k[i] >= xa + yb + 1) {
ok = true;
} else if(((k[i] + xb + ya + 1) & 1) == 0 && k[i] >= xb + ya + 1) {
ok = true;
}
cout << (ok ? "YES" : "NO") << endl;
}
return 0;
}
void tarjan(int u) {
vis[u] = true;
for(int i = 0; i < G[u].size(); i++) {
if(vis[G[u][i]]) continue;
deep[G[u][i]] = deep[u] + 1;
tarjan(G[u][i]);
merge(G[u][i], u);
//注意u和G[u][i]的顺序<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span> 参见函数实现处注释
}
for(int i = 0; i < Gq[u].size(); i++) {
if(!vis[Gq[u][i].to]) continue;
Q[Gq[u][i].num] = deep[u] + deep[Gq[u][i].to] - 2 * deep[ find(Gq[u][i].to) ];
}
}
void add_query(int x, int y, int num) {
Gq[x].push_back(query(y, num));
Gq[y].push_back(query(x, num));
}
//并查集
void merge(int u, int v) {
fa[find(u)] = find(v);
//注意<span class="bd-box"><h-char class="bd bd-beg"><h-inner>:</h-inner></h-char></span>一定要把深度小的结点并到深度大的节点下<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>否则会出错
//我这里是在调用的时候保证了这一点<span class="bd-box"><h-char class="bd bd-beg"><h-inner>,</h-inner></h-char></span>也可以选择在实现的时候判断一下
}
int find(int u) {
return (fa[u] == u ? u : fa[u] = find(fa[u]));
}