最近公共祖先(LCA) 洛谷 3379 LCA

来源:互联网 发布:百度seo技术视频 编辑:程序博客网 时间:2024/05/16 05:33

题目描述

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。

分析

直接上tarjan
水了一道模板(c++的)。
顺便复习一下。

code

#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;struct arr{    int x,y;    int w;    int next;}edge[2000000],problem[2000000];//edge存边,problem存问题。 int ls[2000000],ls_p[2000000];//对应上面。 int n,m,root;int nn,nm;int v[2000000];//记录是否来过。 int f[2000000];//并查集数组。 int find(int x)//并查集查找。 {    if (f[x]==x) return x;    else{        f[x]=find(f[x]);        return f[x];    }}void merge(int x,int y)//并查集合并。{    int x1,y1;    x1=find(x);    y1=find(y);    f[x1]=y1;}void add(int x,int y)//添加边,建树。 {    nn++;    edge[nn].x=x;    edge[nn].y=y;    edge[nn].next=ls[x];    ls[x]=nn;    nn++;    edge[nn].x=y;    edge[nn].y=x;    edge[nn].next=ls[y];    ls[y]=nn;}void add_p(int x,int y)//tarjan算法,要求储存问题。 {    nm++;    problem[nm].x=x;    problem[nm].y=y;    problem[nm].next=ls_p[x];    ls_p[x]=nm;    nm++;    problem[nm].x=y;    problem[nm].y=x;    problem[nm].next=ls_p[y];    ls_p[y]=nm;}void tarjan(int r,int x)//tarjan算法正文。 {    for (int i=ls[x];i!=0;i=edge[i].next)    {        if (edge[i].y==r) continue;        tarjan(x,edge[i].y);        v[edge[i].y]=1;        merge(edge[i].y,x);    }    for (int i=ls_p[x];i!=0;i=problem[i].next)    {        if (v[problem[i].y])                problem[i].w=find(problem[i].y);    }}int main(){    scanf("%d%d%d",&n,&m,&root);    for (int i=1;i<=n-1;i++)    {        int x,y;        scanf("%d %d",&x,&y);        add(x,y);    }    for (int i=1;i<=m;i++)    {        int x,y;        scanf("%d %d",&x,&y);        add_p(x,y);    }    // 输入。     for (int i=1;i<=n;i++)        f[i]=i;    //并查集初始化。     tarjan(0,root);    for (int i=1;i<=nm;i++)    {        if (!problem[i].w) continue;        printf("%d\n",problem[i].w);    }}
1 0
原创粉丝点击