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

题意概括:

给一棵 N 个结点 N-1 条边的树,和 M 次查询;

形式是:先给根结点 然后 给与这个根结点相连的 子节点。

查询的对儿给得有点放荡不羁,需要处理一下空格、回车、括号。。。

解题思路:

虽说表面上看是一道裸得 LCA 模板题(简单粗暴Tarjan)

但是细节还是要注意:

本题没有给 查询数 M 的范围(RE了两次)所以要投机取巧一下不使用记录每对查询的 LCA。

本题是多测试样例,注意初始化!!!

AC code:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #define INF 0x3f3f3f3f
  7 #define LL long long
  8 using namespace std;
  9 const int MAXN = 1e3+10;
 10 struct Edge{int v, w, nxt;}edge[MAXN<<1];
 11 struct Query
 12 {
 13     int v, id;
 14     Query(){};
 15     Query(int _v, int _id):v(_v), id(_id){};
 16 };
 17 vector<Query> q[MAXN];
 18
 19 int head[MAXN], cnt;
 20 int fa[MAXN], ans[MAXN<<1], no[MAXN];
 21 bool vis[MAXN], in[MAXN];
 22 int N, M;
 23
 24 void init()
 25 {
 26     memset(head, -1, sizeof(head));
 27     memset(in, false, sizeof(in));
 28     memset(vis, false, sizeof(vis));
 29     //memset(ans, 0, sizeof(ans));
 30     memset(no, 0, sizeof(no));
 31     cnt = 0;
 32     for(int i = 0; i <= N; i++)
 33         fa[i] = i, q[i].clear();
 34 }
 35
 36 int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}
 37
 38 void AddEdge(int from, int to)
 39 {
 40     edge[cnt].v = to;
 41     edge[cnt].nxt = head[from];
 42     head[from] = cnt++;
 43 }
 44
 45 void Tarjan(int s, int f)
 46 {
 47     int root = s;
 48     fa[s] = s;
 49     for(int i = head[s]; i != -1; i = edge[i].nxt)
 50     {
 51         int Eiv = edge[i].v;
 52         if(Eiv == f) continue;
 53         Tarjan(Eiv, s);
 54         fa[getfa(Eiv)] = s;
 55     }
 56     vis[s] = true;
 57     for(int i = 0; i < q[s].size(); i++){
 58         //if(vis[q[s][i].v]) ans[q[s][i].id] = getfa(q[s][i].v);
 59         if(vis[q[s][i].v])
 60             no[getfa(q[s][i].v)]++;
 61     }
 62 }
 63
 64 int main()
 65 {
 66     while(~scanf("%d", &N)){
 67         init();
 68         //scanf("%d", &N);
 69         for(int i = 1, u, v, k; i <= N; i++){
 70             scanf("%d:(%d)", &u, &k);
 71             for(int j = 1; j <= k; j++){
 72                 scanf("%d", &v);
 73                 AddEdge(u, v);
 74                 in[v] = true;
 75             }
 76         }
 77         int root = 0;
 78         for(int i = 1; i <= N; i++) if(!in[i]){root = i;break;}
 79         scanf("%d", &M);
 80         int sum = 1, u, v;
 81         while(sum <= M){
 82             while(getchar()!=‘(‘);
 83             scanf("%d%d", &u, &v);
 84             while(getchar()!=‘)‘);
 85             q[u].push_back(Query(v, sum));
 86             q[v].push_back(Query(u, sum));
 87             sum++;
 88         }
 89         Tarjan(root, -1);
 90         /*
 91         for(int i = 1; i <= M; i++){
 92             no[ans[i]]++;
 93         }
 94         */
 95
 96         for(int i = 1; i <= N; i++){
 97             if(no[i]) printf("%d:%d\n", i, no[i]);
 98         }
 99     }
100     return 0;
101 }

原文地址:https://www.cnblogs.com/ymzjj/p/9745762.html

时间: 2024-10-01 03:32:26

POJ 1470 Closest Common Ancestors 【LCA】的相关文章

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

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20073   Accepted: 10631 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转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 1330:Nearest Common Ancestors【lca】

题目大意:唔 就是给你一棵树 和两个点,问你这两个点的LCA是什么 思路:LCA的模板题,要注意的是在并查集合并的时候并不是随意的,而是把叶子节点合到父节点上 #include<cstdio> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> #define maxn 10002 #define MOD 1000000007 using names

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

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

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

传送门 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