1. 程式人生 > >洛谷 P3884 [JLOI2009]二叉樹問題

洛谷 P3884 [JLOI2009]二叉樹問題

玄學之門


題目:

傳送門


分析:

明顯是求公共祖先,所以我們可以採用傳統的 L C A LCA 演算法
對於深度和寬度,我們在預處理就已經解決了,其他都是普通的 L

C A LCA 演算法


程式碼:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring> 
#include<cstdlib>
#include<algorithm>
#include<set>
#include<queue>
#include<vector> #include<map> #include<list> #include<ctime> #include<iomanip> #include<string> #include<bitset> #include<deque> #include<set> #define LL long long #define ch cheap using namespace std; inline LL read() { LL d=0,f=1;char s=getchar
(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } int max(int x,int y) {return x>y? x:y;} int min(int x,int y) {return x<y? x:y;} int n=read(); int ls[250],cnt=0; struct node{ int fr,to; }e[205]; void add(int a,int b) { e[cnt]=(node){b,ls[a]}; ls[a]=cnt++; return; } int p[105][15],d[105],md=0; void dfs(int now,int f) { d[now]=d[f]+1; md=max(md,d[now]); p[now][0]=f; for(int i=1;(1<<i)<=d[now];i++) p[now][i]=p[p[now][i-1]][i-1]; for(int i=ls[now];~i;i=e[i].to) if(e[i].fr!=f) dfs(e[i].fr,now); return; } int lca(int u,int v) { if(d[u]>d[v]) swap(u,v); for(int i=10;i>=0;i--) { if(d[u]<=d[v]-(1<<i)) v=p[v][i]; } if(u==v) return u; for(int i=10;i>=0;i--) { if(p[u][i]!=p[v][i]) u=p[u][i],v=p[v][i]; } return p[u][0]; } int c[15],mc=0; int main() { memset(ls,-1,sizeof(ls)); for(int i=1;i<n;i++) { int a=read(),b=read(); add(a,b);add(b,a); } dfs(1,0); for(int i=1;i<=n;i++) c[d[i]]++; for(int i=1;i<=md;i++) mc=max(mc,c[i]); printf("%d\n%d\n",md,mc); int u=read(),v=read(); int king_power=lca(u,v); printf("%d",(d[u]-d[king_power])*2+d[v]-d[king_power]); return 0; }