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

ac代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<vector>
#include<iostream>
using namespace std;
int n,m;
int head[1010],vis[1010],pre[1010],dig[1010],cnt,flag,a,b,cot[1010],ans[1010];
vector<int>vt[1010];
struct s
{
	int u,v,next;
}edge[1010];
int cmp(const void *a,const void *b)
{
	return *(int *)a-*(int *)b;
}
void init()
{
	memset(vis,0,sizeof(vis));
	memset(head,-1,sizeof(head));
	memset(dig,0,sizeof(dig));
	cnt=0;
	memset(cot,0,sizeof(cot));
	for(int i=0;i<=n;i++)
		vt[i].clear();
}
void add(int u,int v)
{
	edge[cnt].u=u;
	edge[cnt].v=v;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}

int find(int x)
{
	if(x==pre[x])
		return x;
	return find(pre[x]);
}
void tarjan(int u)
{
	pre[u]=u;
	vis[u]=1;
	int i;
	for(i=0;i<vt[u].size();i++)
	{
		int v=vt[u][i];
		if(vis[v])
			cot[find(v)]++;
	}
	for(i=head[u];i!=-1;i=edge[i].next)
	{
		int v=edge[i].v;
		if(!vis[v])
		{
			tarjan(v);
			pre[v]=u;
		}
	}
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		int i,j;
		init();

		for(i=0;i<n;i++)
		{
			int u,num;
			scanf("%d:",&u);
			scanf("(%d)",&num);
			while(num--)
			{
				int v;
				scanf("%d",&v);
				add(u,v);
				dig[v]++;
			}
		}
		int root;
		scanf("%d",&m);
		while(m--)
		{
			while(getchar()!='(');
			scanf("%d %d",&a,&b);
			while(getchar()!=')');
			vt[a].push_back(b);
			vt[b].push_back(a);
		}
		for(i=1;i<=n;i++)
		{
			if(dig[i]==0)
			{
				tarjan(i);
				break;
			}
		}
		for(i=1;i<=n;i++)
		{
			if(cot[i])
			{
				printf("%d:%d\n",i,cot[i]);
			}
		}
	}
}
时间: 2024-08-24 23:19:25

POJ 题目1470 Closest Common Ancestors(LCA)的相关文章

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 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(LCA&amp;RMQ)

题意比较费劲:输入看起来很麻烦.处理括号冒号的时候是用%1s就可以.还有就是注意它有根节点...Q次查询,我是用在线st做的. /************************************************************************* > File Name: 3.cpp > Author: Howe_Young > Mail: [email protected] > Created Time: 2015年10月08日 星期四 19时03分

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 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题目1330 Nearest Common Ancestors(LCA)

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