樹鏈剖分求LCA(假的吧這都被卡,難道是我寫錯了?)
阿新 • • 發佈:2018-12-14
大意
給一個N個節點的樹和M個詢問,對於每次詢問輸出兩點的距離。
樣例:
6 1 2 1 3 2 4 2 5 3 6 2 2 6 5 6
輸出:
3
4
【被卡的程式碼(要麼就是寫錯了)】
#include<bits/stdc++.h> using namespace std; const int MAXN=1e5+10; const int MAXM=3e5+10; int n,m,cnt; int head[MAXN],depth[MAXN],son[MAXN],siz[MAXN],father[MAXN]; int top[MAXN]; int nxt[MAXM],to[MAXM]; int Read() { int i=0,f=1; char c; for(c=getchar();(i>'9'||c<'0')&&c!='-';c=getchar()); if(c=='-') f=-1,c=getchar(); for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0'; return i*f; } void Add(int x,int y) { cnt++; nxt[cnt]=head[x]; head[x]=cnt; to[cnt]=y; } void add(int x,int y) { Add(x,y); Add(y,x); } void dfs1(int u,int fa) { father[u]=fa; siz[u]=0,son[u]=0; for(int i=head[u];i!=-1;i=nxt[i]) { int v=to[i]; if(v!=fa) { depth[v]=depth[u]+1; dfs1(v,u); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } } void dfs2(int u,int fa) { if(u==son[fa]) top[u]=top[fa]; else top[u]=u; for(int i=head[u];i!=-1;i=nxt[i]) { int v=to[i]; if(v!=fa) dfs2(v,u); } } int lca(int x,int y) { if(depth[x]<depth[y]) swap(x,y); while(top[x]!=top[y]) { x=father[top[x]]; if(depth[x]<depth[y]) swap(x,y); } return depth[x]<depth[y]?x:y; } int main() { memset(head,-1,sizeof(head)); n=Read(); for(int i=1;i<n;++i) { int x=Read(),y=Read(); add(x,y); } dfs1(1,-1); dfs2(1,1); m=Read(); for(int i=1;i<=m;++i) { int x=Read(),y=Read(); int res=depth[x]+depth[y]-2*depth[lca(x,y)]; cout<<res<<'\n'; } return 0; }