【题目描述】
“这就是我们最新研制的,世界上第一种可持久化动态计算机病毒,‘创世纪’。”方教授介绍道。
“哦。”主席面无表情地点点头。
“‘创世纪’无法真正杀死透明计算网络,但是可以把它变成傻子。可惜透明计算网络能轻松地辨认出病毒,所以我建议……”
“为什么不伪装呢?”Asm.Def说。
“当然不行,它比我们更懂伪装。”
“我是说,把我们的病毒伪装成杀毒软件。”
方教授震惊地盯着Asm.Def看了一会。“你是个天才。”
Asm.Def想把病毒伪装成杀毒软件,入侵透明计算网络。透明计算网络的文件结构是一棵N个节点的树,每个病毒可以入侵一条路径上的所有节点。但如果两个病毒入侵了同一个节点,由于它们伪装成了杀毒软件,就会自相残杀。Asm.Def不希望这样的情况发生,所以他需要仔细制定入侵计划。为此,他需要频繁地询问,两条路径是否经过同一个节点(即是否相交)。
【输入格式】
第一行两个整数N,Q。
接下来N-1行,每行两个整数a,b,表示(a,b)是树上的一条边。
接下来Q行,每行四个整数s1,t1,s2,t2,表示询问s1~t1的路径是否与s2~t2的路径相交。
【输出格式】
对每个询问,若相交则输出一行”YES”,否则输出一行”NO”。
【样例输入】
6 5 1 2 1 3 2 4 4 5 4 6 1 1 5 6 1 2 6 3 2 3 5 6 6 4 3 1 4 3 1 2
【样例输出】
NO YES NO NO YES
【提示】
N,Q<=1000.
1<=s1,t1,s2,t2<=N。
题解:
每次询问搞一次树上差分 在dfs一遍求出点权>=2的点的个数 若为0则不交否则相交时间复杂度O(n^2)
代码:
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1000+10;
vector<int>A[maxn];
int B[maxn];
int ok=0;
int fa[maxn];
int top[maxn];
int size[maxn];
int son[maxn];
int dep[maxn];
inline void dfs1(int x,int f,int d){
dep[x]=d;
fa[x]=f;
size[x]=1;
for(int i=0;i<A[x].size();i++){
int u=A[x][i];
if(u==f)
continue;
dfs1(u,x,d+1);
size[x]+=size[u];
if((size[u]>size[son[x]]&&son[x])||!son[x])
son[x]=u;
}
}
inline void dfs2(int x,int tp){
top[x]=tp;
if(!son[x])
return ;
dfs2(son[x],tp);
for(int i=0;i<A[x].size();i++){
int u=A[x][i];
if(u==fa[x]||u==son[x])
continue;
dfs2(u,u);
}
}
inline void dfs(int x){
for(int i=0;i<A[x].size();i++){
int u=A[x][i];
if(u==fa[x])
continue;
dfs(u);
B[x]+=B[u];
}
if(B[x]>=2)
ok=1;
}
inline int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])
swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y])
return y;
return x;
}
int main(){
freopen("asm_virus.in","r",stdin);
freopen("asm_virus.out","w",stdout);
int n,q;
scanf("%d %d",&n,&q);
int x,y;
for(int i=1;i<n;i++){
scanf("%d %d",&x,&y);
A[x].push_back(y);
A[y].push_back(x);
}
dfs1(1,0,1);
dfs2(1,1);
for(int i=1;i<=q;i++){
memset(B,0,sizeof(B));
ok=0;
scanf("%d %d",&x,&y);
int lc=lca(x,y);
B[x]++;
B[fa[lc]]--;
if(x!=y){
B[y]++;
B[lc]--;
}
scanf("%d %d",&x,&y);
lc=lca(x,y);
B[x]++;
B[fa[lc]]--;
if(x!=y){
B[y]++;
B[lc]--;
}
dfs(1);
if(ok)
puts("YES");
else puts("NO");
}
return 0;
}