zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    POJ 2175 Evacuation Plan 费用流 负圈定理
    POJ 2983 Is the Information Reliable? 差分约束
    codeforces 420B Online Meeting
    POJ 3181 Dollar Dayz DP
    POJ Ant Counting DP
    POJ 1742 Coins DP 01背包
    中国儒学史
    产品思维30讲
    Java多线程编程核心技术
    编写高质量代码:改善Java程序的151个建议
  • 原文地址:https://www.cnblogs.com/huangxf/p/4305650.html
Copyright © 2011-2022 走看看