poj 1470 lca(tarjan做的)
2016-08-21 11:47
274 查看
poj 1470 Closest Common Ancestors
题目:
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:
题意:
就是给一个树之后,再给一堆查询,让你找到每个节点当最近公共子节点的个数,为零不输出,查询比较大(似乎50w左右),输入比较吃 * 。思路:
挺裸的一个题目,用tarjan做的,至于tarjan是什么的话我是看这个的:http://blog.csdn.net/geniusluzh/article/details/6609685
大概意思就是对树进行一次后序遍历,每次访问到了一个节点a,如果有一个查询的其中一个节点是a,那么看另外一个节点b,如果b节点已经访问过了,那么他们的lca就是b已经访问过的祖先的父节点(因为,在后序遍历中从b到a是从这里转过来的,这里也就是他们的lca)。
我在那个博客了学了一发存查询的姿势,之前存法差不多,但是一直wa。。
这个存法其实把每个查询存了两遍,但是dfs是只有一遍是a,b都已经访问过的了,所以没有问题(代码有一个bug是如果a==b的话会算两遍,然而似乎并没有这种数据)。
顺便一提输入查询比较坑,在poj讨论群找了这个输入,比较机智。
scanf(” (%d %d)”,&x,&y);
代码:
#include <iostream> #include <stdio.h> #include <vector> #include <string.h> #include <stdlib.h> #define N 940 using namespace std; vector<int>tree ; vector<int>text ; bool root ; int ans ; int father ; bool vis ; int n,q; int finds(int i) { if(father[i]==i) return i; else return father[i]=finds(father[i]); } void init() { memset(root,1,sizeof(root)); memset(vis,0,sizeof(vis)); memset(ans,0,sizeof(ans)); for(int i=1;i<=n;i++) { tree[i].clear(); text[i].clear(); father[i]=i; } } void dfs(int cur) { int len=tree[cur].size(); for(int i=0;i<len;i++) { int t=tree[cur][i]; dfs(t); father[t]=cur; } vis[cur]=true; len=text[cur].size(); for(int i=0;i<len;i++) { int tmp=text[cur][i]; if(vis[tmp]) ans[finds(tmp)]++; } } int main() { while(scanf("%d",&n)!=EOF) { int x,n1,y; init(); for(int i=1;i<=n;i++) { scanf("%d:(%d)\n",&x,&n1); for(int i=1;i<=n1;i++) { scanf("%d",&y); tree[x].push_back(y); root[y]=false; } } scanf("%d",&q); for(int i=1;i<=q;i++) { scanf(" (%d %d)",&x,&y); text[x].push_back(y); text[y].push_back(x); } for(int i=1;i<=n;i++) if(root[i]) { dfs(i); break; } for(int i=1;i<=n;i++) if(ans[i]) printf("%d:%d\n",i,ans[i]); } return 0; }
P.S.:改不出bug,宛如咸鱼,(明显就是么)。
相关文章推荐
- poj 1470 Closest Common Ancestors 【Tarjan 离线 LCA】
- POJ1470 Closest Common Ancestors 【Tarjan的LCA】
- poj 1470--tarjan--LCA
- poj 1470 Closest Common Ancestors 离线算法Tarjan求LCA
- poj1470 Closest Common Ancestors [ 离线LCA tarjan ]
- POJ-1470 Closest Common Ancestors Tarjan-LCA
- (算法)Tarjan离线算法解决LCA问题 (附POJ 1470 Closest Common Ancestors 代码)
- POJ1470 Closest Common Ancestors(最近公共祖先lca,离线Tarjan)
- POJ 1470 Cloest Common Ancestor(用Tarjan查询LCA)
- POJ 1470 LCA tarjan 离线算法
- POJ 1470 Closest Common Ancestors(离线tarjan-LCA)
- poj 1470 Closest Common Ancestors(tarjan离线求lca)
- 【LCA/tarjan】POJ1470-Closest Common Ancestors
- LCA的tarjan求法&&POJ 1470的辛酸历程
- POJ 1470 Closest Common Ancestors【LCA Tarjan】
- poj 1470 关于lca离线tarjan方法的使用
- poj1470 LCA Tarjan
- poj 1470 Closest Common Ancestors (离线LCA Tarjan)
- (算法)Tarjan离线算法解决LCA问题 (附POJ 1470 Closest Common Ancestors 代码)
- POJ 1470 Closest Common Ancestors【LCA Tarjan】