• 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 }
  • 相关阅读:
    Windows文件操作的直接函数调用
    随笔
    XML的四种解析器原理及性能比较
    TVirtualStringTree的图标状态重叠
    使用代码控制TVirtualStringTree的选项
    c 与 c++中的time相关函数
    0x08标志类型的RTMPE、RTMPTE协议分析
    小小的高兴一下
    Scaleform GFx
    delphi类的相互引用
  • 原文地址:https://www.cnblogs.com/huangxf/p/4305650.html
Copyright © 2020-2023  润新知