1. 程式人生 > >每日一道模板題-10/11

每日一道模板題-10/11

題意:

給定一棵 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;
}