poj1330 lca倍增算法模板

来源:互联网 发布:mac识别不了u盘启动盘 编辑:程序博客网 时间:2024/06/05 03:54

上一套基于二分搜索的lca倍增算法模板



#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<string>#include<stack>#include<queue>#include<cmath>#include<stack>#include<list>#include<map>#include<set>typedef long long ll;#define exp 1e-8#define up(i,x,y) for(i=x;i<=y;i++)#define down(i,x,y) for(i=x;i>=y;i--)#define mem(a,x) memset(a,x,sizeof(a))using namespace std;const int N = 5005*2;//最大节点个数const int MAX_LOG_V =25;//比最大深度大一点就好vector<int>G[N];int root;int parent[MAX_LOG_V][N];int depth[N];int f[N];void dfs(int v,int p,int d){    parent[0][v]=p;    depth[v]=d;    for(int i=0;i<G[v].size();i++)    {        if(G[v][i]!=p)dfs(G[v][i],v,d+1);    }}void init(int V){        dfs(root,-1,0);    for(int k=0;k+1<MAX_LOG_V;k++)    {        for(int v=0;v<V;v++)        {            if(parent[k][v]<0)                parent[k+1][v]=-1;            else parent[k+1][v]=parent[k][parent[k][v]];        }    }}int lca(int u,int v){    if(depth[u]>depth[v])swap(u,v);    for(int k=0;k+1<MAX_LOG_V;k++)    {        if((depth[v]-depth[u])>>k&1)            v=parent[k][v];    }//使u和v的深度相同    if(u==v)return u;//深度相同且恰好为同一个节点 直接return        for(int k=MAX_LOG_V-1;k>=0;k--)//找到u和v的最近公共祖先    {        if(parent[k][u]!=parent[k][v])        {            u=parent[k][u];            v=parent[k][v];        }    }    return parent[0][u];}int main(){        int T,i,j,k,m,n;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(i=0;i<N;i++)        {            G[i].clear();        }        mem(f,-1);        for(i=1;i<=n-1;i++)        {            int a,b;            scanf("%d%d",&a,&b);            f[b-1]=a-1;//求root的编号 习惯从0开始编号            G[a-1].push_back(b-1);//双向图            G[b-1].push_back(a-1);        }        for(i=0;i<n;i++)//求root的编号        {            if(f[i]==-1)            {                root=i;                break;            }        }        //mem(parent,-1);        init(n);        scanf("%d%d",&i,&j);        printf("%d\n",lca(i-1,j-1)+1);            }}