每日一道模板題-10/11
阿新 • • 發佈:2018-12-14
題意:
給定一棵 n 個點的樹,Q 個詢問,每次詢問點 x 到點 y兩點之間的距離。
分析:
沒什麼好分析的……
程式碼:
#include<bits/stdc++.h> #define N 100009 using namespace std; int n,q; int nxt[2*N],to[2*N],head[N],w[N*2],cnt=0; void add(int x,int y,int z){ nxt[++cnt]=head[x];head[x]=cnt; to[cnt]=y;w[cnt]=z; } int fa[N][25],d[N],dep[N]; void dfs(int u,int fu){ fa[u][0]=fu; for(int e=head[u];e;e=nxt[e]){ int v=to[e]; if(v==fu) continue; d[v]=d[u]+1;dep[v]=dep[u]+1; dfs(v,u); } } int getlca(int x,int y){ if(dep[x]<dep[y]) swap(x,y); for(int i=20;i>=0;--i) if(dep[fa[x][i]]>=dep[y]) x=fa[x][i]; if(x==y) return x; for(int i=20;i>=0;--i) { if(fa[x][i]!=fa[y][i]){ x=fa[x][i];y=fa[y][i]; } } return fa[x][0]; } int main(){ scanf("%d",&n); int i,j,k,x,y; for(i=1;i<n;++i){ scanf("%d%d",&x,&y); add(x,y,1); } d[1]=0;dep[1]=1; dfs(1,0); for(j=1;j<=20;++j) for(i=1;i<=n;++i) fa[i][j]=fa[fa[i][j-1]][j-1]; scanf("%d",&q); for(i=1;i<=q;++i){ scanf("%d%d",&x,&y); int lca=getlca(x,y); printf("%d\n",d[x]+d[y]-d[lca]*2); } return 0; }