您的位置:首页 > 其它

POJ 1330 Nearest Common Ancestors

2016-01-27 16:23 330 查看
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|1

struct 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|1

int 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|1

int 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: