题意
一颗多叉树,给四个点,求有无公共点。
基本思路
倍增LCA,若$dep(lca(a,b))>dep(lca(cd))$,若有公共点,则$lca(lca(a,b),c)==lca(a,b)$或$lca(lca(a,b),d)==lca(a,b)$,反之亦然
倍增做法
1 #include<bits/stdc++.h> 2 #define FOR(i,a,b) for(int i=a;i<b;i++) 3 #define FOR2(i,a,b) for(int i=a;i<=b;i++) 4 #define ll long long 5 #define INF 0x7f7f7f7f; 6 #define MAXN 200010 7 #define MOD 10007 8 #define MAXJUMP 22 9 using namespace std; 10 typedef struct{ 11 int from,to,next; 12 }EDGE;EDGE edges[MAXN]; 13 int a,b,c,d,n,m,s,ed=0,head[MAXN]; 14 int jump[MAXN][30],dep[MAXN]; 15 inline int read() 16 { 17 char ch=getchar(); 18 int x=0,f=1; 19 while((ch>'9'||ch<'0')&&ch!='-') 20 ch=getchar(); 21 if(ch=='-') 22 { 23 f=-1; 24 ch=getchar(); 25 } 26 while('0'<=ch&&ch<='9') 27 { 28 x=x*10+ch-'0'; 29 ch=getchar(); 30 } 31 return x*f; 32 } 33 inline void put(int x) 34 { 35 if(x==0) 36 { 37 putchar('0'); 38 putchar(' '); 39 return; 40 } 41 int num=0; 42 char c[25]; 43 while(x) 44 { 45 c[++num]=(x%10)+48; 46 x/=10; 47 } 48 while(num) 49 putchar(c[num--]); 50 putchar(' '); 51 return ; 52 } 53 inline int log2(int x) 54 { 55 int k=0;while(x>1)x=x>>1,k++;return k; 56 } 57 inline void add(int a,int b) 58 { 59 edges[++ed].from=a; 60 edges[ed].to=b; 61 edges[ed].next=head[a]; 62 head[a]=ed; 63 return; 64 } 65 66 void dfs(int cur,int pre) 67 { 68 jump[cur][0]=pre; 69 dep[cur]=dep[pre]+1; 70 for(int i=1;i<=MAXJUMP;i++) 71 {//记录跳点 72 jump[cur][i]=jump[jump[cur][i-1]][i-1]; 73 } 74 for(int i=head[cur];i;i=edges[i].next) 75 { 76 if(edges[i].to==pre)continue; 77 dfs(edges[i].to,cur); 78 } 79 } 80 int lca(int a,int b) 81 { 82 if(dep[a]<dep[b]) 83 { 84 swap(a,b); 85 } 86 for(int i=MAXJUMP;i>=0;i--) 87 { 88 if((1<<i)<=dep[a]-dep[b]) 89 { 90 a=jump[a][i]; 91 } 92 } 93 if(a==b) 94 return a; 95 for(int i=MAXJUMP;i>=0;i--) 96 { 97 if(jump[a][i]!=jump[b][i]) 98 a=jump[a][i],b=jump[b][i]; 99 } 100 return jump[a][0];//返回共同父节点 101 } 102 vector<int>q; 103 int main() 104 {//倍增 105 n=read();m=read(); 106 FOR(i,1,n) 107 { 108 a=read();b=read(); 109 add(a,b);add(b,a);q.push_back(b); 110 } 111 sort(q.begin(),q.end()); 112 FOR(i,0,q.size()) 113 { 114 if(i+1!=q[i]) 115 {//确定起点 116 s=i+1;break; 117 } 118 } 119 120 dfs(s,0); 121 FOR(i,0,m) 122 { 123 a=read();b=read();c=read();d=read(); 124 int ab=lca(a,b);//cout<<ab<<" "; 125 int cd=lca(c,d);//cout<<cd<<" "; 126 127 if(dep[ab]>dep[cd]) 128 { 129 if(ab==lca(ab,c)||ab==lca(ab,d)) cout<<"Y"<<endl; 130 else cout<<"N"<<endl; 131 } 132 else { 133 if(cd==lca(cd,a)||cd==lca(cd,b)) cout<<"Y"<<endl; 134 else cout<<"N"<<endl; 135 } 136 137 } 138 return 0; 139 }