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[maxN];
vector<int> query[maxN];
int find(int u)
{
	return f[u]==u?u:f[u]=find(f[u]);
} 

void tarjan(int root)
{
	int i;
	f[root]=root;
	vis[root]=1;
	for(i=query[root].size()-1;i>=0;--i){
		int p=query[root][i];
		if(vis[p]==1)
			++cnt[find(p)];
	}
	int s=son[root];
	while(s){
		tarjan(s);
		f[s]=root;
		s=bro[s];
	}
}
int main()
{
	char ch1[4],ch2[4],ch3[4];
	int i;
	while(scanf("%d",&n)==1){
		memset(par,0,sizeof(par));
		memset(son,0,sizeof(son));
		memset(bro,0,sizeof(bro));
		for(i=1;i<=n;++i) query[i].clear();
		for(i=1;i<=n;++i){
			scanf("%d%1s%1s%d%1s",&u,ch1,ch2,&t,&ch3);
			while(t--){
				scanf("%d",&v);
				par[v]=1;
				bro[v]=son[u];
				son[u]=v;
			}
		}
		for(i=1;i<=n;++i)
			if(par[i]==0) break;
		scanf("%d",&m);
		while(m--){
			scanf("%1s%d%d%1s",ch1,&x,&y,ch2);
			query[x].push_back(y);
			if(x!=y) query[y].push_back(x);
		}
		memset(cnt,0,sizeof(cnt));
		memset(vis,0,sizeof(vis));
		tarjan(i);
		for(i=1;i<=n;++i)
			if(cnt[i])	printf("%d:%d\n",i,cnt[i]);
	}
	return 0;
} 
时间: 2024-08-02 11:42:35

poj 1470 Closest Common Ancestors tarjan求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 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来记录查询数组,这样每次都只需要循环某节点的邻接查询点就可以了

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

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