poj----(1470)Closest Common Ancestors(LCA)

Closest Common Ancestors

Time Limit: 2000MS   Memory Limit: 10000K
Total Submissions: 15446   Accepted: 4944

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 the closest common ancestor of u and v in the tree. The closest common ancestor of two nodes u and v is the node w that is an ancestor of both u and v and has the greatest depth in the tree. A node can be its own ancestor (for example in Figure 1 the ancestors of node 2 are 2 and 5)

Input

The data set, which is read from a the std input, starts with the tree description, in the form:

nr_of_vertices

vertex:(nr_of_successors) successor1 successor2 ... successorn

...

where vertices are represented as integers from 1 to n ( n <= 900
). The tree description is followed by a list of pairs of vertices, in
the form:

nr_of_pairs

(u v) (x y) ...

The input file contents several data sets (at least one).

Note that white-spaces (tabs, spaces and line breaks) can be used freely in the input.

Output

For
each common ancestor the program prints the ancestor and the number of
pair for which it is an ancestor. The results are printed on the
standard output on separate lines, in to the ascending order of the
vertices, in the format: ancestor:times

For example, for the following tree:

Sample Input

5
5:(3) 1 4 2
1:(0)
4:(0)
2:(1) 3
3:(0)
6
(1 5) (1 4) (4 2)
      (2 3)
(1 3) (4 3)

Sample Output

2:1
5:5

Hint

Huge input, scanf is recommended.

Source

Southeastern Europe 2000

给你一棵树,要你找出一些节点的最近公共祖先

代码:

  1 /*poj 1470*/
  2 #include<iostream>
  3 #include<vector>
  4 #include<cstdio>
  5 #include<cstring>
  6 #include<cstdlib>
  7 using namespace std;
  8 const int maxn=902;
  9 vector<int> tree[maxn],qus[maxn];
 10 int rank[maxn],father[maxn];
 11 bool vis[maxn];
 12 int rudu[maxn];
 13 int lroot[maxn];
 14 int ans[maxn];
 15
 16 void init(int n){
 17      memset(vis,0,sizeof(char)*(n+1));
 18      memset(rudu,0,sizeof(int)*(n+1));
 19      memset(lroot,0,sizeof(int)*(n+1));
 20      memset(ans,0,sizeof(int)*(n+1));
 21     for(int i=1;i<=n;i++){
 22         father[i]=i;
 23         rank[i]=1;
 24         tree[i].clear();
 25         qus[i].clear();
 26     }
 27 }
 28
 29 int find(int a){
 30    while(a!=father[a])
 31          a=father[a];
 32     return a;
 33 }
 34
 35 void Union(int a,int b)
 36 {
 37     int x=find(a);
 38     int y=find(b);
 39     if(x==y) return ;
 40     if(rank[x]<rank[y]){
 41       rank[y]+=rank[x];
 42       father[x]=y;
 43     }
 44     else {
 45      rank[x]+=rank[y];
 46      father[y]=x;
 47     }
 48 }
 49
 50 void LCA(int u)
 51 {
 52   lroot[u]=u;
 53   //vis[u]=1; 不能放在这里
 54   int len=tree[u].size();
 55   for(int i=0;i<len;i++){
 56       LCA(tree[u][i]);
 57       Union(u,tree[u][i]);
 58       lroot[find(u)]=u;
 59   }
 60   vis[u]=1;
 61   int ss=qus[u].size();
 62   for(int i=0;i<ss;i++){
 63         if(vis[qus[u][i]]){
 64             ans[lroot[find(qus[u][i])]]++;
 65             //return ;
 66         }
 67   }
 68 }
 69
 70 int main()
 71 {
 72     int n,m,t,u1,u2;
 73     freopen("test.in","r",stdin);
 74     while(scanf("%d",&n)!=EOF){
 75           init(n);
 76       for(int i=0;i<n;i++){
 77             getchar();
 78         scanf("%d:(%d))",&u1,&m);
 79          for(int j=0;j<m;j++){
 80              scanf("%d",&u2);
 81              tree[u1].push_back(u2);
 82              rudu[u2]++;
 83          }
 84         }
 85       scanf("%d",&t);
 86       for(int i=0;i<t;i++)
 87       {
 88           scanf("%*1s%d%d%*1s",&u1,&u2);
 89           qus[u1].push_back(u2);
 90           qus[u2].push_back(u1);
 91       }
 92       for(int i=1;i<=n;i++)
 93       {
 94           if(rudu[i]==0)
 95         {
 96             LCA(i);
 97             break;
 98         }
 99       }
100       for(int i=1;i<=n;i++){
101           if(0!=ans[i])
102             printf("%d:%d\n",i,ans[i]);
103       }
104     }
105 return 0;
106 }
时间: 2024-12-14 18:48:22

poj----(1470)Closest Common Ancestors(LCA)的相关文章

POJ 题目1470 Closest Common Ancestors(LCA)

Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 16671   Accepted: 5319 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 the

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(离线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

POJ 1470 Closest Common Ancestors 离线LCA

实测查询量大概是25W左右,离线搞比较快. #include <cstdio> #include <cstring> #include <algorithm> #include <map> #include <set> #include <bitset> #include <queue> #include <stack> #include <string> #include <iostream

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 1330 Nearest Common Ancestors(树)

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17628   Accepted: 9335 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each

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

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