问题 C: 约会
时间限制: 2 Sec 内存限制: 256 MB题目描述
输入
输出
样例输入
4
1 2
1 3
2 4
1
2 3
样例输出
1
提示
一道不错的LCA的题。考试时想到正解,无奈打错LCA,超时了35分。。(一个新坑)
这里是需要讨论的。
一,如果求出的路径长为奇数,一定没有合法解。
二,如果x==y,输出n。
三,如果dep[x]==dep[y],设k=LCA(x,y),fx为x祖先,且dep[fx]==dep[k]+1,fy同理,
则ans=n-size[fx]-size[fy],
四,剩下就是正常情况了,设h为x,y距离,(设dep[x]>dep[y])k为x祖先,dep[k]==dep[x]-h/2.
ans=size[k]-size[fx],fx为x祖先,dep[fx]==dep[k]+1.
神犇ljy云:“我如果会LCA,我今天就AK了。”然并卵,我也是啊。。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100000
using namespace std;
int read()
{
int sum=0,f=1;char x=getchar();
while(x<'0'||x>'9'){if(x=='-')f=-1;x=getchar();}
while(x>='0'&&x<='9'){sum=(sum<<1)+(sum<<3)+x-'0';x=getchar();}
return sum*f;
}
int n,m,adj[N+5],e;
int f[N+5],dep[N+5],size[N+5],p[100005][20];
struct road
{
int v,next;
}lu[N*2+5];
void add(int u,int v){lu[++e].v=v;lu[e].next=adj[u];adj[u]=e;}
void dfs(int x,int deep)
{
size[x]=1;
dep[x]=deep;
for(int i=adj[x];i;i=lu[i].next)
{
int to=lu[i].v;
if(to!=f[x])
{
f[to]=x;
dfs(to,deep+1);
size[x]+=size[to];
}
}
}
int get(int x,int y)
{
int i,j;
if(dep[x]<dep[y])swap(x,y);
for(i=0;(1<<i)<=dep[x];i++);
i--;
for(j=i;j>=0;j--)
if(dep[x]-(1<<j)>=dep[y])
x=p[x][j];
if(x==y)return x;
for(j=i;j>=0;j--)
if(p[x][j]!=-1&&p[x][j]!=p[y][j])
{
x=p[x][j];
y=p[y][j];
}
return f[x];
}
void init()
{
for(int j=0;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
p[i][j]=-1;
for(int i=1;i<=n;i++)p[i][0]=f[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i<=n;i++)
if(p[i][j-1]!=-1)
p[i][j]=p[p[i][j-1]][j-1];
}
int zhao(int x,int h)
{
int i,j;
for(i=0;(1<<i)<=dep[x];i++);
i--;
for(j=i;j>=0;j--)
if(h-(1<<j)>=0)
{
h-=(1<<j);
x=p[x][j];
}
return x;
}
int main()
{
// freopen("date.in","r",stdin);
// freopen("date.out","w",stdout);
n=read();
int x,y;
for(int i=1;i<n;i++)
{
x=read();y=read();
add(x,y);add(y,x);
}
f[1]=0;
dfs(1,1);
init();
m=read();
int w,q;
while(m--)
{
x=read();y=read();
if(x==y){printf("%d\n",n);continue;}
int k=get(x,y);
int h=dep[x]+dep[y]-2*dep[k];
if(h%2){printf("0\n");continue;}
if(dep[x]==dep[y])
{
w=zhao(x,dep[x]-dep[k]-1);
q=zhao(y,dep[y]-dep[k]-1);
printf("%d\n",n-size[w]-size[q]);
}
else
{
if(dep[x]>dep[y])swap(x,y);
q=zhao(y,h/2),w=zhao(y,h/2-1);
printf("%d\n",size[q]-size[w]);
}
}
}