POJ1330.Nearest Common Ancestors——最近公共祖先(dfs+ST在线算法)

来源:互联网 发布:mac下制作dos 编辑:程序博客网 时间:2024/06/05 20:53

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

LCA转RMQ

2596K 47MS C++

#include<iostream>#include<cstring>#include<cstdio>#include<string>#include<algorithm>const int maxn=10010;using namespace std;int rmq[maxn<<1];//深度序列int F[maxn<<1];//欧拉序列,长度为2*node_num-1int P[maxn];//表示节点i在欧拉序列中第一次出现的位置bool in[maxn];//入度int cnt;int n;//节点数struct ST{    int mm[maxn<<1];//2^j次方    int dp[maxn<<1][20];//从i开始长度为2^j的区间中深度最小的值的下标    void init(int n){        mm[0]=-1;        for(int i=1;i<=n;++i){            mm[i]=((i&(i-1))==0)? mm[i-1]+1:mm[i-1];            dp[i][0]=i;        }        for(int j=1;j<=mm[n];++j){            for(int i=1;i+(1<<j)-1<=n;++i){                dp[i][j]=rmq[dp[i][j-1]]<rmq[dp[i+(1<<(j-1))][j-1]]?dp[i][j-1]:dp[i+(1<<(j-1))][j-1];            }        }    }    int query(int a,int b){        if(a>b) swap(a,b);        int k=mm[b-a+1];        return rmq[dp[a][k]]<=rmq[dp[b-(1<<k)+1][k]]?dp[a][k]:dp[b-(1<<k)+1][k];//返回在欧拉序列中的下标    }}st;struct Edge{    int to,next;}edge[maxn<<1];int head[maxn],tot;void addedge(int u,int v){    edge[tot].to=v;    edge[tot].next=head[u];    head[u]=tot++;}void init(){    tot=0;    memset(head,-1,sizeof(head));}void dfs(int u,int pre,int dep){//dfs遍历求得欧拉序列,深度序列,每个节点在欧拉序列中第一次出现的位置    F[++cnt]=u;    rmq[cnt]=dep;    P[u]=cnt;    for(int i=head[u];i!=-1;i=edge[i].next){        int v=edge[i].to;        if(v==pre) continue;        dfs(v,u,dep+1);        F[++cnt]=u;        rmq[cnt]=dep;    }}void lca_init(int root,int node_num){//预处理    cnt=0;    dfs(root,root,0);    st.init(2*node_num-1);}int query_lca(int u,int v){    return F[st.query(P[u],P[v])];}int main(){    int T,u,v;    cin>>T;    while(T--){        init();        memset(in,false,sizeof(in));        scanf("%d",&n);        for(int i=1;i<n;++i){            scanf("%d%d",&u,&v);            addedge(u,v);            addedge(v,u);            in[v]=true;        }        int root;        for(int i=1;i<=n;++i){            if(in[i]==false){                root=i;                break;            }        }        lca_init(root,n);        scanf("%d%d",&u,&v);        printf("%d\n",query_lca(u,v));    }    return 0;}
0 0