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\n",i,barrel[i]);
90         }
91         scanf("%*[^0-9]");
92     }
93 }

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

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

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

posted @ 2018-01-16 16:52  JZYshuraK_彧  阅读(156)  评论(0编辑  收藏  举报