hdu4409 最近公共祖先

题意: 给出一个家谱, 并且给出了一种遍历的顺序, 现在有3种询问

1、求出一种遍历的顺序,使同一代的人字典序小的一定出现在前边。

2、问某个人一共有几个亲兄弟姐妹。

3、求两个人的最近公共祖先。

思路:这道题很简单, 不过就是很麻烦, 求最近公共祖先我是用的很朴素的算法。当对边排序的时候首选vector。

AC代码:

View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <string>
  5 #include <queue>
  6 #include <vector>
  7 #include <map>
  8 #include <algorithm>
  9 using namespace std;
 10 const int N = 31000;
 11 
 12 struct node
 13 {
 14     int v;
 15     string name;
 16     node (int a=0, string b="")
 17     {
 18         v = a;
 19         name = b;
 20     }
 21     bool friend operator < (node A, node B)
 22     {
 23         return A.name < B.name;
 24     }
 25 };
 26 
 27 vector<node>g[N];
 28 map<string,int> mp;
 29 string str[N];
 30 int f[N], n, lp[N], last[N], step;
 31 
 32 void init()
 33 {
 34     for(int i=1; i<=n; i++)
 35         g[i].clear();
 36     mp.clear();
 37     int tp=0, now, u, v;
 38     char ss[200];
 39     for(int i=1; i<=n; i++)
 40     {
 41         scanf("%s", ss);
 42         if(i == 1)
 43         {
 44             tp++;
 45             mp[ss] = tp;
 46             str[tp] = ss;
 47             last[0] = tp;
 48             continue;
 49         }
 50         for(int j=0; ss[j]; j++)
 51         {
 52             if(ss[j] != '.')
 53             {
 54                 u = last[j-1];
 55                 tp++;
 56                 mp[ss+j] = tp;
 57                 str[tp] = ss+j;
 58                 last[j] = tp;
 59                 f[tp] = u;
 60                 g[u].push_back(node(tp,ss+j));
 61                 break;
 62             }
 63         }
 64     }
 65     for(int i=1; i<=n; i++)
 66      {
 67          sort(g[i].begin(), g[i].end());
 68      }
 69 }
 70 
 71 void dfs(int u)
 72  {
 73      int v;
 74      node tp;
 75      lp[u] = ++step;
 76      for(int i=0; i<g[u].size(); i++)
 77       {
 78           dfs(g[u][i].v);
 79       }
 80  }
 81 
 82 void dfs1(int u, int now)
 83  {
 84      for(int i=1; i<=now; i++)
 85       printf(".");
 86      cout<<str[u]<<endl;
 87      for(int i=0; i<g[u].size(); i++)
 88       {
 89           dfs1(g[u][i].v, now+1);
 90       }
 91  }
 92 
 93 void lca(int uu,int vv)
 94   {
 95       int u = uu, v = vv;
 96       while(u!=v)
 97       {
 98           while(lp[u]>lp[v]&&u!=v)
 99           {
100              u=f[u];
101           }
102           while(lp[v]>lp[u]&&u!=v)
103            {
104              v=f[v];
105            }
106       }
107      if(u == uu || u == vv)
108       {
109          cout<<str[f[u]]<<endl;
110       }
111      else cout<<str[u]<<endl;
112   }
113 
114 
115 void solve()
116  {
117      step = 0;
118      dfs(1);
119      int m;
120      char s1[200], s2[200];
121      int u, v;
122      string a, b;
123      scanf("%d", &m);
124      while(m--)
125       {
126           scanf("%s", s1);
127           if(s1[0] == 'L')
128            {
129                dfs1(1,0);
130            }
131            else if(s1[0] == 'b')
132            {
133                 scanf("%s",s1);
134                 a = s1;
135                 u = mp[a];
136                 if(u == 1) printf("1\n");
137                 else printf("%d\n",g[f[u]].size());
138            }
139            else
140            {
141                scanf("%s%s", s1, s2);
142                a = s1;
143                b = s2;
144                u = mp[a];
145                v = mp[b];
146                lca(u, v);
147            }
148       }
149  }
150 
151 int main()
152 {
153     while(scanf("%d", &n) != EOF && n)
154     {
155         init();
156         solve();
157     }
158     return 0;
159 }

 

 

posted @ 2012-10-02 19:11  Gu Feiyang  阅读(188)  评论(0)    收藏  举报