LCA 最近公共祖先 [POJ 1330]

http://poj.org/problem?id=1330

View Code
const int MM = 22222;
int N, in[MM], root;
int head[MM],NE;
struct Edge{
    int u,v,next;
}edge[MM];
bool vis[MM];
int ief,level;
int dp[MM][17]; //节点数*2
int E[MM], L[MM], H[MM]; //节点数*2

int log_2(int x) {
    int res=-1;
    while(x) x>>=1,res++;
    return res;
}
void add_edge(int u,int v) {
    edge[NE].u=u, edge[NE].v=v; 
    edge[NE].next=head[u], head[u]=NE++;
}
void get_data() {
    int i,j,k,x,y;
    scanf("%d",&N);
    NE=0;
    memset(head,-1,sizeof(head));
    memset(in,0,sizeof(in));
    for(i=1;i<N;i++) {
        scanf("%d%d",&x,&y);
        in[y]++;
        add_edge(x,y), add_edge(y,x);
    }
    for(i=1;i<=N;i++) if(in[i]==0) {root=i;break;}
}
void dfs(int u) {
    int i,j,k,v;
    E[++ief]=u; H[u]=ief; L[ief]=++level;
    for(i=head[u];i!=-1;i=edge[i].next) {
        v=edge[i].v;
        if(!vis[v]) {
            vis[v]=true; dfs(v); E[++ief]=u; L[ief]=--level;
        }
    }
}
void init_rmq() {
    int i,j,k,lim;
    for(i=1;i<=ief;i++) dp[i][0]=i;
    k=log_2(ief);
    for(i=1;i<=k;i++) {
        lim=ief-(1<<i)+1;
        for(j=1;j<=lim;j++) {
            if(L[dp[j][i-1]]>L[dp[j+(1<<(i-1))][i-1]])
                dp[j][i]=dp[j+(1<<(i-1))][i-1];
            else dp[j][i]=dp[j][i-1];
        }
    }
}
int query(int x,int y) {
    if(x>y) swap(x,y);
    int k=log_2(y-x+1);
    if(L[dp[x][k]]>L[dp[y-(1<<k)+1][k]]) 
        return dp[y-(1<<k)+1][k];
    else return dp[x][k];
}
void solve() {
    int i,j,k,x,y;
    memset(vis,false,sizeof(vis)); 
    vis[1]=true, level=ief=0;
    dfs(root); init_rmq();
    scanf("%d%d",&x,&y);
    printf("%d\n",E[query(H[x],H[y])]);
}

int main() {
    int ca; scanf("%d",&ca);
    while(ca--) get_data(),solve();
    return 0;
}

 

posted @ 2013-05-05 16:45  zhang1107  阅读(148)  评论(0编辑  收藏  举报