zoukankan      html  css  js  c++  java
  • Cloesest Common Ancestors

    Cloesest Common Ancestors

        题目大意:给出一个n个节点的树,m组询问求两点LCA。

        注释:n<=900.

          想法:这题一看,我去,这不傻题吗?一看读入方式,完了,懵逼了... ...这题是考读入啊一大堆乱七八糟的东西,真正有用的只有里面的数... ...然后,我学了两个比较有用的东西。

          1.scanf("%*d");其中,*表示读完就删,所以可以用来处理本题。

          2.强大的nc+read(),在此不做介绍。

          总之,初学LCA,这是另一道朴素的LCA,用桶记录即可。

        最后,附上丑陋的代码... ...

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define N 1000
     6 using namespace std;
     7 int to[N],nxt[N],tot,fa[N],deep[N],barrel[N];
     8 int head[N];
     9 bool v[N];
    10 // inline char nc()
    11 // {
    12 //     static char buf[100000],*p1,*p2;
    13 //     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    14 // }
    15 // inline void read(int &x)
    16 // {
    17 //     x=0;char c=nc();
    18 //     while(!isdigit(c))c=nc();
    19 //     while(isdigit(c))x=x*10+c-'0',c=nc();
    20 // }
    21 inline void add(int x,int y)
    22 {
    23     to[++tot]=y;
    24     nxt[tot]=head[x];
    25     head[x]=tot;
    26 }
    27 void dfs(int x,int pre,int step)
    28 {
    29     fa[x]=pre;
    30     deep[x]=step;
    31     for(int i=head[x];i;i=nxt[i])
    32     {
    33         dfs(to[i],x,step+1);
    34     }
    35 }
    36 inline int lca(int x,int y)
    37 {
    38     if(deep[x]<deep[y]) swap(x,y);
    39     while(deep[x]>deep[y]) x=fa[x];
    40     while(x!=y) x=fa[x],y=fa[y];
    41     return x;
    42 }
    43 int main()
    44 {
    45     int n,m;
    46     int a,b;
    47     char s[5];
    48     while(~scanf("%d",&n))
    49     {
    50         tot=0;
    51         memset(head,0,sizeof(head));
    52         memset(v,false,sizeof(v));
    53         memset(barrel,0,sizeof(barrel));
    54 
    55 
    56         // scanf("%d",&n);
    57         for(int i=1;i<=n;i++)
    58         {
    59             // read(a);
    60             scanf("%*[^0-9]%d",&a);
    61             // read(m);
    62             scanf("%*[^0-9]%d",&m);
    63             for(int i=1;i<=m;i++)
    64             {
    65                 scanf("%*[^0-9]%d",&b);
    66                 add(a,b);
    67                 v[b]=1;
    68             }
    69         }
    70         int root;
    71         for(int i=1;i<=n;i++)
    72         {
    73             if(!v[i])
    74             {
    75                 root=i;
    76                 break;
    77             }
    78         }
    79         dfs(root,root,0);
    80         scanf("%*[^0-9]%d",&m);
    81         for(int i=1;i<=m;i++)
    82         {
    83             scanf("%*[^0-9]%d",&a);
    84             scanf("%*[^0-9]%d",&b);
    85             barrel[lca(a,b)]++;
    86         }
    87         for(int i=1;i<=n;i++)
    88         {
    89             if(barrel[i]!=0) printf("%d:%d
    ",i,barrel[i]);
    90         }
    91         scanf("%*[^0-9]");
    92     }
    93 }

        小结:LCA的朴素算法还是很有用的啊... ... 

          错误:1.在读取链式前向星时一定要记得是i=nxt[i]而不是nxt[i]。

             2.最后仍然会剩余一个括号,别忘记了它会影响下一组数据。

  • 相关阅读:
    .NE 学习概要
    (转)工作之路---记录LZ如何在两年半的时间内升为PM
    XP下Winform背景透明问题
    CSE(Corrupted State Exceptions) 严重异常处理办法
    (转)C#模拟键盘鼠标事件
    (转).net项目技术选型总结
    (转)MSMQ续
    (转)MSMQ(消息队列)
    (转)TCP三次握手
    Socket编程初探
  • 原文地址:https://www.cnblogs.com/ShuraK/p/8297513.html
Copyright © 2011-2022 走看看