题意:
给一个n点的数,以1为根的树,
询问m个x,y,a,b,k
问x,y两点暂时联通,a点到b点能不能刚好满足过k条线
能输出yes,不能输出no
思路:
树上两点之间的距离用lca算出来,因为可以反复横跳,所以只要两点之间的距离小于等于k,然后与k的奇偶性一样就是yes
一共有三条路
dis(a,b)
dis(a,x)+dis(y,b)+1
dis(a,y)+dis(x,b)+1
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define il inline 5 #define it register int 6 #define inf 0x3f3f3f3f 7 #define lowbit(x) (x)&(-x) 8 #define mem(a,b) memset(a,b,sizeof(a)) 9 #define mod 998244353 10 const int maxn=1e5+10; 11 struct node{ 12 int next,v; 13 }a[maxn<<1]; 14 int t,m,n,head[maxn],tot,x,y,a1,b,k,f,depth[maxn],fa[maxn][20]; 15 void add(int u,int v){ 16 a[tot].next=head[u]; 17 a[tot].v=v;head[u]=tot++; 18 } 19 void build(int uu){ 20 queue<int>q; 21 depth[uu]=1; 22 q.push(1); 23 while(!q.empty()){ 24 int u=q.front();q.pop(); 25 for(it i=head[u];~i;i=a[i].next){ 26 int v=a[i].v; 27 if(depth[v]==-1){ 28 depth[v]=depth[u]+1;q.push(v); 29 fa[v][0]=u; 30 for(it j=1;j<=19;j++){ 31 int arc=fa[v][j-1]; 32 fa[v][j]=fa[arc][j-1]; 33 } 34 } 35 } 36 } 37 } 38 int lca(int x,int y){ 39 if(depth[x]<depth[y])swap(x,y); 40 for(it i=19;i>=0;i--){ 41 if(depth[fa[x][i]]>=depth[y]){ 42 x=fa[x][i]; 43 } 44 } 45 if(x==y)return x; 46 for(it i=19;i>=0;i--){ 47 if(fa[x][i]!=fa[y][i]){ 48 x=fa[x][i]; 49 y=fa[y][i]; 50 } 51 } 52 return fa[x][0]; 53 } 54 int dis(int u,int v){ 55 int d=lca(u,v); 56 return depth[u]+depth[v]-2*depth[d]; 57 } 58 int main(){ 59 mem(head,-1);mem(depth,-1);tot=0; 60 scanf("%d",&n); 61 for(it i=0;i<n-1;i++){ 62 int u,v; 63 scanf("%d%d",&u,&v);add(u,v);add(v,u); 64 } 65 depth[0]=0;build(1); 66 scanf("%d",&m); 67 while(m--){ 68 scanf("%d%d%d%d%d",&x,&y,&a1,&b,&k); 69 int kk=k;k%=2; 70 int d1=dis(a1,b),d2=dis(a1,x)+dis(y,b)+1,d3=dis(a1,y)+dis(x,b)+1; 71 if((d1%2==k && kk>=d1) || (d2%2==k && kk>=d2)||(d3%2==k && kk>=d3)){printf("YES\n");} 72 else{printf("NO\n");} 73 } 74 return 0; 75 } 76 /* 77 5 78 1 2 79 2 3 80 3 4 81 4 5 82 5 83 1 3 1 2 2 84 1 4 1 3 2 85 1 4 1 3 3 86 4 2 3 3 9 87 5 2 3 3 9 88 YES 89 YES 90 NO 91 YES 92 NO 93 */