zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    032 代码复用与函数递归
    031 实例7-七段数码管绘制
    030 函数的定义与使用
    029 函数和代码复用
    2.4 Buffer
    2.3 字符串链接
    2.2 去除字符串特别字符
    2.1 字符串查询
    存储数据_文件读写
    template模板
  • 原文地址:https://www.cnblogs.com/zhang1107/p/3061155.html
Copyright © 2011-2022 走看看