POJ 1470 Closest Common Ancestors【最近公共祖先LCA】

题目链接:http://poj.org/problem?id=1470

题目大意:给出一棵树,再给出若干组数(a,b),输出节点a和节点b的最近公共祖先(LCA)

就是很裸的LCA,但是我用的是《挑战程序设计竞赛》上的“基于二分搜索的算法求LCA”,我看网上用的都是tarjan算法。但是我的代码不知道为什么提交上去 wrong answer,自己想的很多测试数据也都和题解结果一样,不知道错在哪里,所以把代码保存一下,留待以后解决。。。。。。

如果读者有什么建议,希望提出来,感激不尽!

#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;

#define N 911
#define LOG_N 11
int times[N];
bool findroot[N];
#include <vector>

vector<int> g[N];//
int root;
int parent[LOG_N][N];
int depth[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)//预处理出parent
{
    dfs(root,-1,0);
    for(int k=0;k+1<LOG_N;k++)
    {
        for(int v=1;v<=V;v++)
        {
            if(parent[k][v]<0) parent[k+1][v]=-1;
            else parent[k+1][v]=parent[k][parent[k][v]];
        }
    }
}
//计算u和v的LCA
int lca(int u,int v)
{
    //让u和v向上走到同一深度
    if(depth[u]>depth[v]) swap(u,v);
    for(int k=0;k<LOG_N;k++)
    {
        if((depth[v]-depth[u])>>k&1)
        {
            v=parent[k][v];
        }
    }
    if(u==v) return u;
    //利用二分搜索计算LCA
    for(int k=LOG_N-1;k>=0;k--)
    {
        if(parent[k][u]!=parent[k][v])
        {
            u=parent[k][u];
            v=parent[k][v];
        }
    }
    return parent[0][u];
}
int main()
{
    freopen("D:/in.txt","r",stdin);
    int n,t,a;
    while(~scanf("%d",&n))
    {
        char ch1[2],ch2[2];//吸收掉那个可恶的括号什么的东西
        memset(times,0,sizeof(times));
        memset(parent,0,sizeof(parent));
        memset(depth,0,sizeof(depth));
        memset(findroot,0,sizeof(findroot));
        for(int i=1;i<=N;i++)
            g[i].clear();
        for(int i=0;i<n;i++)
        {
            scanf("%d:(%d)",&a,&t);
            for(int j=0;j<t;j++)
            {
                int temp;
                scanf("%d",&temp);
                g[a].push_back(temp);
                findroot[temp]=true;
            }
        }
        for(int i=1;i<=n;i++)
            if(!findroot[i])
            {
                root=i;
                break;
            }
        init(n);
        int qn,fir,sec;
        scanf("%d",&qn);
        for(int i=0;i<qn;i++)
        {
            scanf("%1s%d%d%1s)",ch1,&fir,&sec,ch2);
            times[lca(fir,sec)]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(times[i])
                printf("%d:%d\n",i,times[i]);
        }
        printf("\n");
    }
    return 0;
}

POJ 1470 Closest Common Ancestors【最近公共祖先LCA】

时间: 2024-12-19 07:23:58

POJ 1470 Closest Common Ancestors【最近公共祖先LCA】的相关文章

poj 1470 Closest Common Ancestors 【Tarjan 离线 LCA】

题目:poj 1470 Closest Common Ancestors 题意:给出一个树,一些询问.求LCA的个数. 分析:很简单的模板题目,但是模板不够优秀,一直wa...RE,各种错误一下午,终于发现自己模板的漏洞了. AC代码: #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; #define N 1010 #

POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)

LCA问题的tarjan解法模板 LCA问题 详细 1.二叉搜索树上找两个节点LCA 1 public int query(Node t, Node u, Node v) { 2 int left = u.value; 3 int right = v.value; 4 5 //二叉查找树内,如果左结点大于右结点,不对,交换 6 if (left > right) { 7 int temp = left; 8 left = right; 9 right = temp; 10 } 11 12 whi

POJ 1470 Closest Common Ancestors LCA题解

本题也是找LCA的题目,不过要求多次查询,一般的暴力查询就必然超时了,故此必须使用更高级的方法,这里使用Tarjan算法. 本题处理Tarjan算法,似乎输入处理也挺麻烦的. 注意: 因为查询的数据会极大,故此使用一个数组记录所有查询数据就会超时的.我就载在这里了.查了好久才想到这点.因为我使用了一个vector容器记录了查询数据,故此每次都循环这组这么大的数据,就超时了.----解决办法:使用一个vector<int> quest来记录查询数组,这样每次都只需要循环某节点的邻接查询点就可以了

POJ 1470 Closest Common Ancestors 【LCA】

任意门:http://poj.org/problem?id=1470 Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 22519   Accepted: 7137 Description Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pa

POJ 1470 Closest Common Ancestors 采用树结构的非线性表编程

A - Closest Common Ancestors(8.4.9) Time Limit:2000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Description Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the prog

POJ 1470 Closest Common Ancestors

传送门 Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 17306   Accepted: 5549 Description Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines

poj 1470 Closest Common Ancestors LCA

题目链接:http://poj.org/problem?id=1470 Write a program that takes as input a rooted tree and a list of pairs of vertices. For each pair (u,v) the program determines the closest common ancestor of u and v in the tree. The closest common ancestor of two n

POJ - 1470 Closest Common Ancestors(离线Tarjan算法)

1.输出测试用例中是最近公共祖先的节点,以及这个节点作为最近公共祖先的次数. 2.最近公共祖先,离线Tarjan算法 3. /* POJ 1470 给出一颗有向树,Q个查询 输出查询结果中每个点出现次数 */ /* 离线算法,LCATarjan 复杂度O(n+Q); */ #include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int MAXN=1010; co

POJ 1470 Closest Common Ancestors (在线LCA转RMQ)

题目地址:POJ 1470 LCA模板题..输入有点坑,还有输入的第一个结点不一定是根节点. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include