问题 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);continue;} int k=get(x,y); int h=dep[x]+dep[y]-2*dep[k]; if(h%2){printf("0 ");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-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 ",size[q]-size[w]); } } }