HDU 4409 Family Name List ( 模拟 + LCA)

  昨晚脑子发涨,代码写的跟坨屎的,到底没过,今天早晨来看了看,查了几个bug过了。。。

纯模拟+LCA找最近公共祖先,需要注意的几个地方:

1、出处顺序,可以用dfs输出,不过每个dfs里面要开一个vector<>,然后排序。

2、b操作可能出现询问Mr.X,Mr.X的brother个数为1

3、c操作时LCA不能是他两个本身。可以开一个pre,如果是他俩中的一个,再往前找一个就可以了。

200+行的渣代码:

 

View Code
  1 //#pragma comment(linker,"/STACK:327680000,327680000")
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cmath>
  5 #include <vector>
  6 #include <cstring>
  7 #include <algorithm>
  8 #include <string>
  9 #include <set>
 10 #include <functional>
 11 #include <numeric>
 12 #include <sstream>
 13 #include <stack>
 14 #include <map>
 15 #include <queue>
 16 
 17 #define CL(arr, val) memset(arr, val, sizeof(arr))
 18 #define REP(i, n)for((i) = 0; (i) < (n); ++(i))
 19 #define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i))
 20 #define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i))
 21 #define L(x)(x) << 1
 22 #define R(x)(x) << 1 | 1
 23 #define MID(l, r)(l + r) >> 1
 24 #define Min(x, y)x < y ? x : y
 25 #define Max(x, y)x < y ? y : x
 26 #define E(x)(1 << (x))
 27 #define iabs(x) (x) < 0 ? -(x) : (x)
 28 #define OUT(x)printf("%I64d\n", x)
 29 #define lowbit(x)(x)&(-x)
 30 #define Read()freopen("data.in", "r", stdin)
 31 #define Write()freopen("data.out", "w", stdout);
 32 
 33 const double eps = 1e-10;
 34 typedef long long LL;
 35 const int inf = ~0u>>2;
 36 
 37 using namespace std;
 38 
 39 const int N = 30010;
 40 
 41 struct People {
 42     string name;
 43     int lv;
 44     int num;
 45     bool operator < (const People cmp) const {
 46         return name < cmp.name;
 47     }
 48 }p[N];
 49 
 50 
 51 int child[N];
 52 int pre[N], fa[N];
 53 int pp[N];
 54 int n;
 55 
 56 string anc, tmp, tmp2;
 57 map<string, int> numb;
 58 
 59 
 60 struct pnode {
 61     int to;
 62     int next;
 63 } g[N];
 64 
 65 int head[N], t;
 66 class Graph {
 67 public:
 68     void init() {CL(head, -1); t = 0;}
 69     void add(int u, int v) {g[t].to = v; g[t].next = head[u]; head[u] = t++;}
 70 } G;
 71 
 72 
 73 int D[N<<1], E[N<<1], R[N<<1];
 74 int Min[N<<1][21];
 75 
 76 class RMQ {
 77 public:
 78 
 79     void build(int n) {
 80         int i, j, m;
 81         for(i = 1; i <= n; ++i) Min[i][0] = i;
 82         m = int(log(double(n))/log(2.0));
 83         FOR(j, 1, m) {
 84             FOR(i, 1, n - (1<<j) + 1) {
 85                 if(D[Min[i][j-1]] < D[Min[i+(1<<(j-1))][j-1]]) {
 86                     Min[i][j] = Min[i][j-1];
 87                 } else {
 88                     Min[i][j] = Min[i+(1<<(j-1))][j-1];
 89                 }
 90 
 91             }
 92         }
 93     }
 94 
 95     int query(int s, int e) {
 96         int k = log(double(e - s + 1))/log(2.0);
 97         if(D[Min[s][k]] < D[Min[e-(1<<k) + 1][k]])   return  Min[s][k];
 98         else    return Min[e-(1<<k) + 1][k];
 99     }
100 } Q;
101 
102 
103 class LCA {
104 public:
105     int cnt;
106     bool vis[N];
107 
108     void init() {
109         CL(D, 0);
110         CL(E, 0); CL(R, 0);
111         CL(vis, 0); cnt = 0;
112     }
113 
114     void dfs(int t, int dep) {
115         D[++cnt] = dep;
116         E[cnt] = t;
117 
118         if(!vis[t]) {
119             R[t] = cnt;
120             vis[t] = true;
121         }
122 
123         for(int i = head[t]; i != -1; i = g[i].next) {
124             dfs(g[i].to, dep + 1);
125             D[++cnt] = dep;
126             E[cnt] = t;
127         }
128     }
129     void build() {
130         init();
131         dfs(0, 0);
132         Q.build(cnt);
133     }
134     int query(int x, int y) {
135         x = R[x], y = R[y];
136         if(x > y)   swap(x, y);
137         return E[Q.query(x, y)];
138     }
139 }LCA;
140 
141 
142 void init() {
143     CL(child, 0); CL(pre, -1);
144     CL(fa, 0);
145     numb.clear();
146     G.init();
147 }
148 
149 void read_data() {
150     int i, j;
151     cin >> anc;
152     p[0].name = anc;
153     p[0].lv = 0;
154     p[0].num = 0;
155     for(i = 1; i < n; ++i) {
156         cin >> tmp;
157         j = 0;
158         while(tmp[j] == '.' && j < static_cast<int>(tmp.size())) ++j;
159         p[i].lv = j;
160         p[i].num = i;
161         p[i].name = tmp.substr(j);
162         numb[p[i].name] = i;
163         fa[j] = i; pre[i] = fa[j-1];
164         G.add(fa[j-1], i);
165         child[fa[j-1]]++;
166     }
167 }
168 
169 void print(People a) {
170     int i = a.lv;
171     while(i--)  putchar('.');
172     cout << a.name << endl;
173 }
174 
175 void List(int t) {
176     print(p[t]);
177     vector<People> q;
178     int r = 0, i;
179     for(i = head[t]; i != -1; i = g[i].next) {
180         q.push_back(p[g[i].to]);
181         r++;
182     }
183     if(r == 0)  return ;
184     sort(q.begin(), q.end());
185     for(i = 0; i < r; ++i) {
186         List(q[i].num);
187     }
188 }
189 
190 char op[2];
191 void solve() {
192     int q, i, j, pos;
193     scanf("%d", &q);
194     while(q--) {
195         scanf("%s", op);
196         if(op[0] == 'L') {
197             List(0);
198         } else if(op[0] == 'b') {
199             cin >> tmp;
200             i = numb[tmp];
201             if(i == 0)  puts("1");
202             else    printf("%d\n", child[pre[i]]);
203         } else {
204             cin >> tmp >> tmp2;
205             i = numb[tmp]; j = numb[tmp2];
206             pos = LCA.query(i, j);
207             if(pos == i)    pos = pre[i];
208             if(pos == j)    pos = pre[j];
209             cout << p[pos].name << endl;
210         }
211     }
212 }
213 
214 int main() {
215     //Read();
216 
217     while(scanf("%d", &n), n) {
218         init();
219         read_data();
220 
221         LCA.build();
222         solve();
223     }
224     return 0;
225 
226 }
posted @ 2012-09-26 08:29  AC_Von  阅读(373)  评论(0编辑  收藏  举报