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
",i,vis[i]);
122     }
123     return 0;
124 }
原文地址:https://www.cnblogs.com/huangxf/p/4305650.html