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

题目描述:给出一棵树的节点之间的信息,然后给出一些询问,每次询问是求出两个节点的LCA。统计每个节点被作为询问中LCA的次数并输出。

算法分析:LCA离线算法,从算法思想和思维上并不难,可以说是一道模板题,但这道题的输入有点麻烦,处理一下输入就可以了。

另外ZOJ1141也是这道题,我在ZOJ上面AC了

但是在POJ上WA了,最后处理输入之后AC了。

看看程序想了想,应该POJ上面形如5:(5)这样的输入中有可能不是冒号和括号,而是其他的符号吧。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<algorithm>
  7 #include<vector>
  8 #define inf 0x7fffffff
  9 using namespace std;
 10 const int maxn=900+10;
 11 const int max_log_maxn=10;
 12
 13 int n,root;
 14 vector<int> G[maxn];
 15 int father[max_log_maxn][maxn],d[maxn];
 16 int vis[maxn];
 17
 18 void dfs(int u,int p,int depth)
 19 {
 20     father[0][u]=p;
 21     d[u]=depth;
 22     int num=G[u].size();
 23     for (int i=0 ;i<num ;i++)
 24     {
 25         int v=G[u][i];
 26         if (v != p) dfs(v,u,depth+1);
 27     }
 28 }
 29
 30 void init()
 31 {
 32     dfs(root,-1,0);
 33     for (int k=0 ;k+1<max_log_maxn ;k++)
 34     {
 35         for (int i=1 ;i<=n ;i++)
 36         {
 37             if (father[k][i]<0) father[k+1][i]=-1;
 38             else father[k+1][i]=father[k][father[k][i] ];
 39         }
 40         father[k][root]=root;
 41     }
 42 }
 43
 44 int LCA(int u,int v)
 45 {
 46     if (d[u]>d[v]) swap(u,v);
 47     for (int k=0 ;k<max_log_maxn ;k++)
 48     {
 49         if ((d[v]-d[u])>>k & 1)
 50             v=father[k][v];
 51     }
 52     if (u==v) return u;
 53     for (int k=max_log_maxn-1 ;k>=0 ;k--)
 54     {
 55         if (father[k][u] != father[k][v])
 56         {
 57             u=father[k][u];
 58             v=father[k][v];
 59         }
 60     }
 61     return father[0][u];
 62 }
 63
 64 int main()
 65 {
 66     while (scanf("%d",&n)!=EOF)
 67     {
 68         int u,num,v;
 69         for (int i=0 ;i<=n ;i++) G[i].clear();
 70         memset(vis,0,sizeof(vis));
 71         char str[100];
 72         memset(str,0,sizeof(str));
 73         char ch[2],ch2[2],ch3[2];
 74         for (int i=0 ;i<n ;i++)
 75         {
 76             int u=0,num=0;
 77             scanf("%d%1s%1s%d%1s",&u,ch,ch2,&num,ch3);
 78 //            scanf("%s",str);
 79 //            int u=0,num=0;
 80 //            int len=strlen(str);
 81 //            int j=0;
 82 //            for (j=0 ;j<len && str[j]!=‘:‘;j++) u=u*10+str[j]-‘0‘;
 83 //            for (j=j+2 ;j<len && str[j]!=‘)‘;j++) num=num*10+str[j]-‘0‘;
 84             while (num--)
 85             {
 86                 scanf("%d",&v);
 87                 G[u].push_back(v);
 88                 vis[v]=1;
 89             }
 90         }
 91         for (int i=1 ;i<=n ;i++) if (!vis[i]) {root=i;break; }
 92         init();
 93         memset(vis,0,sizeof(vis));
 94         scanf("%d",&num);
 95         memset(str,0,sizeof(str));
 96         //getchar();
 97         for (int j=0 ;j<num ;j++)
 98         {
 99             scanf("%1s%d%d%1s",ch,&u,&v,ch2);
100 //            gets(str);
101 //            int u=0,v=0;
102 //            int len=strlen(str);
103 //            int i=0;
104 //            for (i=1 ;i<len && str[i]>=‘0‘ && str[i]<=‘9‘ ;i++)
105 //                u=u*10+str[i]-‘0‘;
106 //            while (i<len)
107 //            {
108 //                if (str[i]>=‘0‘ && str[i]<=‘9‘) break;
109 //                i ++ ;
110 //            }
111 //            while (i<len)
112 //            {
113 //                if (str[i]==‘)‘) break;
114 //                v=v*10+str[i]-‘0‘;
115 //                i ++ ;
116 //            }
117             int ans=LCA(u,v);
118             vis[ans]++;
119         }
120         for (int i=1 ;i<=n ;i++)
121             if (vis[i]) printf("%d:%d\n",i,vis[i]);
122     }
123     return 0;
124 }
时间: 2024-10-10 23:33:57

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