POJ 1330 Nearest Common Ancestors

来源:互联网 发布:易语言json解析模块 编辑:程序博客网 时间:2024/06/05 03:53

LCA 的 入门级题目。

现在给你一棵树,求u和v的最近公共祖先是那个节点。

方法有很多种,可以用RMQ,tarjan或者是回溯打标记。

#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#include<vector>#include<iostream>#include<string>#include<set>#include<map>#include<algorithm>#include<complex>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")#define nn 10010#define ll long long#define ULL unsiged long long#define mod 1000000007#define inf oxfffffffffff#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1struct node{    int fa;    bool vis;}p[nn];void init(int n){    for(int i=0;i<=n;i++)    {        p[i].fa=i;        p[i].vis=false;    }}int lca(int x,int y){    p[x].vis=true;    x=p[x].fa;    while(p[x].fa!=x)    {        p[x].vis=true;        x=p[x].fa;    }    while(p[y].fa!=y)    {        if(p[y].vis)            break;        y=p[y].fa;    }    return y;}int main(){    int t,n,u,v;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        init(n);        for(int i=1;i<n;i++)        {            scanf("%d%d",&u,&v);            p[v].fa=u;        }        scanf("%d%d",&u,&v);        printf("%d\n",lca(u,v));    }    return 0;}

#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#include<vector>#include<iostream>#include<string>#include<set>#include<map>#include<algorithm>#include<complex>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")#define nn 10010#define ll long long#define ULL unsiged long long#define mod 1000000007#define inf oxfffffffffff#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1int fa[nn],edg[nn];int u,v,ans,cur;struct node{    int to;    int next;}adj[nn];int head[nn],vis[nn],flag;int findfa(int x){    if(fa[x]==x) return x;    return fa[x]=findfa(fa[x]);}void init(int n){    memset(edg,0,sizeof(edg));    memset(head,-1,sizeof(head));    memset(vis,0,sizeof(vis));    for(int i=0;i<=n;i++)        fa[i]=i;    cur=1;    flag=0;}void add(int u,int v){    adj[cur].to=v;    adj[cur].next=head[u];    head[u]=cur++;}void tarjan(int x){    fa[x]=x;    vis[x]=1;    for(int i=head[x]; i!=-1 && !flag; i=adj[i].next)    {        int v=adj[i].to;        if(!vis[v])        {            tarjan(v);            fa[v]=x;        }    }    if(x==u && vis[v])    {        ans=findfa(v);        flag=1;    }    else if(x==v && vis[u])    {        ans=findfa(u);        flag=1;    }}int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        init(n);        for(int i=1;i<n;i++)        {            scanf("%d%d",&u,&v);            add(u,v);            edg[v]++;        }        scanf("%d%d",&u,&v);        for(int i=1;i<=n;i++)        {            if(edg[i]==0)            {                tarjan(i);                break;            }        }        printf("%d\n",ans);    }    return 0;}

#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#include<vector>#include<iostream>#include<string>#include<set>#include<map>#include<algorithm>#include<complex>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")#define nn 10010#define ll long long#define ULL unsiged long long#define mod 1000000007#define inf oxfffffffffff#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1int edg[nn],vis[nn];int u,v,ans,cur,dfn;struct node{    int to;    int next;}adj[nn];int head[nn];int dp[nn<<1][20],deep[nn];int pos[nn],hash[nn<<1],low[nn<<1];void init(int n){    memset(edg,0,sizeof(edg));    memset(head,-1,sizeof(head));    memset(vis,0,sizeof(vis));    cur=1;    dfn=1;}void add(int u,int v){    adj[cur].to=v;    adj[cur].next=head[u];    head[u]=cur++;}void dfs(int u){    int tmp=dfn;    low[dfn]=dfn;    pos[u]=dfn;    hash[dfn++]=u;    for(int i=head[u]; i!=-1;i=adj[i].next)    {        int v=adj[i].to;        dfs(v);        low[dfn]=tmp;        hash[dfn++]=u;    }}void solve(int n){    for(int i=1;i<=n;i++)        dp[i][0]=low[i];    for(int j=1;(1<<j)<=n;j++)        for(int i=1;i+(1<<j)-1<=n;i++)            dp[i][j]=min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);}int rmq(int u,int v){    u=pos[u];    v=pos[v];    if(u>v) swap(u,v);    int k=(int)(log(v*1.0-u+1)/log(2.0));    int tmp1=u;    int tmp2=v-(1<<k)+1;    return hash[min(dp[tmp1][k],dp[tmp2][k])];}int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        init(n);        for(int i=1;i<n;i++)        {            scanf("%d%d",&u,&v);            add(u,v);            edg[v]++;        }        scanf("%d%d",&u,&v);        for(int i=1;i<=n;i++)            if(edg[i]==0)            {                dfs(i);                break;            }        solve(n*2-1);        printf("%d\n",rmq(u,v));    }    return 0;}


0 0
原创粉丝点击