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
#define M 20010

struct Node
{
    int to,val;
};
vector<Node> g[N];
struct ask{
    int u,v,lca;
};
vector<ask> e;
vector<int> query[N];
int fa[N],ance[N],dir[N];
bool vis[N];

inline void add_Node(int u ,int v,int w)
{
    g[u].push_back((Node){v,w});
    g[v].push_back((Node){u,w});
}

inline void add_ask(int u ,int v )
{
    e.push_back((ask){u,v,-1});
    e.push_back((ask){v,u,-1});
    int len = e.size()-1;
    query[v].push_back(len);
    query[u].push_back(len-1);
}

int find(int x){
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}

void Tarjan(int u,int val)
{
    vis[u] = true;
    ance[u] = fa[u] = u;
    dir[u] = val;
    for(int i=0;i<g[u].size();i++)
    {
        Node tmp = g[u][i];
        if(!vis[tmp.to])
        {
            Tarjan(tmp.to,val+tmp.val);
            fa[tmp.to] = u;
        }
    }
    for(int i=0;i<query[u].size();i++)
    {
        int num = query[u][i];
        ask& tmp = e[num];
        if(vis[tmp.v])
        {
            tmp.lca = e[num^1].lca = ance[find(tmp.v)];
        }
    }
}
int ans[N],flag[N];
void Clear(int n)
{
    memset(vis,false,sizeof(vis));
    memset(ans,0,sizeof(ans));
    memset(flag,0,sizeof(flag));
    for(int i=0;i<=n;i++){
        g[i].clear();
        query[i].clear();
    }
    e.clear();
}
int main()
{
    //freopen("Input.txt","r",stdin);
    int n;
    int u,x,m;
    char ch;
    while(scanf("%d",&n)!=EOF)
    {
        Clear(n);
        for(int i=1;i<=n;i++)
        {
            scanf("%d:(%d)",&u,&m);
            while(m--)
            {
                scanf("%d",&x);
                flag[x]=true;
                add_Node(x,u,1);
            }
        }
        int Q;
        scanf("%d",&Q);
        for(int i=1;i<=Q;i++)
        {
            cin>>ch;
            scanf("%d%d",&u,&x);
            cin>>ch;
            add_ask(u,x);
        }
        int root;
        for(int i=1;i<=n;i++)
          if(!flag[i])
          {
              root=i;
              break;
          }
        Tarjan(root,0);
        for(int i = 0;i< Q;i++)
        {
            ans[e[i*2].lca]++;
        }
        for(int i = 1; i<= N;i++)
        {
            if(ans[i])
                printf("%d:%d\n",i,ans[i]);
        }
    }
    return 0;
}
时间: 2024-10-12 05:15:28

poj 1470 Closest Common Ancestors 【Tarjan 离线 LCA】的相关文章

poj 1470 Closest Common Ancestors tarjan求lca和树的孩子兄弟表示

题意: 给一棵树和若干查询点对,求这些点对的lca. 分析: tarjan求lca的模板题,树还是用孩子兄弟表示法比较简洁. 代码: //poj 1470 //sepNINE #include <iostream> #include <vector> using namespace std; const int maxN=1024; int n,u,v,t,m,x,y;; int par[maxN],son[maxN],bro[maxN],f[maxN],cnt[maxN],vis

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 1330 Nearest Common Ancestors(Tarjan离线LCA)

Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each node is labeled with an integer from {1, 2,...,16}. Node 8 is the root of the tree. Node x is an ancestor of

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 题目大意:给出一棵树,再给出若干组数(a,b),输出节点a和节点b的最近公共祖先(LCA) 就是很裸的LCA,但是我用的是<挑战程序设计竞赛>上的"基于二分搜索的算法求LCA",我看网上用的都是tarjan算法.但是我的代码不知道为什么提交上去 wrong answer,自己想的很多测试数据也都和题解结果一样,不知道错在哪里,所以把代码保存一下,留待以后解决...... 如果读者有什么建议,希望提出来,

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

传送门 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 采用树结构的非线性表编程

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