倍增LCA模板

来源:互联网 发布:c语言不同数据类型运算 编辑:程序博客网 时间:2024/06/06 00:19

poj 1330即一道倍增LCA模板题,注意在倍增往上跳时每个while语句的终止条件,WA了几次就是因为跳飞了。。。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>using namespace std;const int maxn=10004;int n;int head[maxn],num,in[maxn];int dep[maxn],f[maxn][14];struct EDGE {    int t,nxt;}e[maxn<<1];inline void init() {    memset(f,-1,sizeof(f));    memset(dep,0,sizeof(dep));    memset(in,0,sizeof(in));    memset(head,-1,sizeof(head));    num=0;}inline void adde(int u,int v) {    e[num].nxt=head[u];    e[num].t=v;    head[u]=num++;}void dfs(int p,int fa) {    for (int i=head[p];i!=-1;i=e[i].nxt) {        int j=e[i].t;        dep[j]=dep[p]+1;        f[j][0]=p;//initialize dp[j][0]        dfs(j,p);    }}inline void init_dp() {    for (int j=1;(1<<j)<=n;j++)//start from 1        for (register int i=1;i<=n;i++)            if (f[i][j-1]!=-1)                f[i][j]=f[f[i][j-1]][j-1];}inline int lca(int a,int b) {    int i=0;    if (dep[b]>dep[a]) swap(a,b);//ensure that a is deeper    while ((1<<i)<dep[a]) ++i;    for (int j=i;j>=0;j--)        if (dep[a]-(1<<j)>=dep[b]) a=f[a][j];    if (a==b) return a;    for (int j=i;j>=0;j--)        if (f[a][j]!=-1&&f[b][j]!=-1&&f[a][j]!=f[b][j])            a=f[a][j],b=f[b][j];    return f[a][0];}int main() {    int u,v,kase;    scanf("%d",&kase);    while (kase--) {        init();        scanf("%d",&n);        for (register int i=1;i<n;i++) {                    scanf("%d%d",&u,&v);            adde(u,v);++in[v];        }        for (register int i=1;i<=n;i++)            if (!in[i]) {dfs(i,0);break;}        init_dp();        scanf("%d%d",&u,&v);        printf("%d\n",lca(u,v));    }    return 0;}