HDU 4409 Family Name List ( 模拟 + LCA)
2012-09-26 08:29
381 查看
昨晚脑子发涨,代码写的跟坨屎的,到底没过,今天早晨来看了看,查了几个bug过了。。。
纯模拟+LCA找最近公共祖先,需要注意的几个地方:
1、出处顺序,可以用dfs输出,不过每个dfs里面要开一个vector<>,然后排序。
2、b操作可能出现询问Mr.X,Mr.X的brother个数为1
3、c操作时LCA不能是他两个本身。可以开一个pre,如果是他俩中的一个,再往前找一个就可以了。
200+行的渣代码:
View Code
纯模拟+LCA找最近公共祖先,需要注意的几个地方:
1、出处顺序,可以用dfs输出,不过每个dfs里面要开一个vector<>,然后排序。
2、b操作可能出现询问Mr.X,Mr.X的brother个数为1
3、c操作时LCA不能是他两个本身。可以开一个pre,如果是他俩中的一个,再往前找一个就可以了。
200+行的渣代码:
View Code
//#pragma comment(linker,"/STACK:327680000,327680000") #include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define REP(i, n)for((i) = 0; (i) < (n); ++(i)) #define FOR(i, l, h)for((i) = (l); (i) <= (h); ++(i)) #define FORD(i, h, l)for((i) = (h); (i) >= (l); --(i)) #define L(x)(x) << 1 #define R(x)(x) << 1 | 1 #define MID(l, r)(l + r) >> 1 #define Min(x, y)x < y ? x : y #define Max(x, y)x < y ? y : x #define E(x)(1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x)printf("%I64d\n", x) #define lowbit(x)(x)&(-x) #define Read()freopen("data.in", "r", stdin) #define Write()freopen("data.out", "w", stdout); const double eps = 1e-10; typedef long long LL; const int inf = ~0u>>2; using namespace std; const int N = 30010; struct People { string name; int lv; int num; bool operator < (const People cmp) const { return name < cmp.name; } }p ; int child ; int pre , fa ; int pp ; int n; string anc, tmp, tmp2; map<string, int> numb; struct pnode { int to; int next; } g ; int head , t; class Graph { public: void init() {CL(head, -1); t = 0;} void add(int u, int v) {g[t].to = v; g[t].next = head[u]; head[u] = t++;} } G; int D[N<<1], E[N<<1], R[N<<1]; int Min[N<<1][21]; class RMQ { public: void build(int n) { int i, j, m; for(i = 1; i <= n; ++i) Min[i][0] = i; m = int(log(double(n))/log(2.0)); FOR(j, 1, m) { FOR(i, 1, n - (1<<j) + 1) { if(D[Min[i][j-1]] < D[Min[i+(1<<(j-1))][j-1]]) { Min[i][j] = Min[i][j-1]; } else { Min[i][j] = Min[i+(1<<(j-1))][j-1]; } } } } int query(int s, int e) { int k = log(double(e - s + 1))/log(2.0); if(D[Min[s][k]] < D[Min[e-(1<<k) + 1][k]]) return Min[s][k]; else return Min[e-(1<<k) + 1][k]; } } Q; class LCA { public: int cnt; bool vis ; void init() { CL(D, 0); CL(E, 0); CL(R, 0); CL(vis, 0); cnt = 0; } void dfs(int t, int dep) { D[++cnt] = dep; E[cnt] = t; if(!vis[t]) { R[t] = cnt; vis[t] = true; } for(int i = head[t]; i != -1; i = g[i].next) { dfs(g[i].to, dep + 1); D[++cnt] = dep; E[cnt] = t; } } void build() { init(); dfs(0, 0); Q.build(cnt); } int query(int x, int y) { x = R[x], y = R[y]; if(x > y) swap(x, y); return E[Q.query(x, y)]; } }LCA; void init() { CL(child, 0); CL(pre, -1); CL(fa, 0); numb.clear(); G.init(); } void read_data() { int i, j; cin >> anc; p[0].name = anc; p[0].lv = 0; p[0].num = 0; for(i = 1; i < n; ++i) { cin >> tmp; j = 0; while(tmp[j] == '.' && j < static_cast<int>(tmp.size())) ++j; p[i].lv = j; p[i].num = i; p[i].name = tmp.substr(j); numb[p[i].name] = i; fa[j] = i; pre[i] = fa[j-1]; G.add(fa[j-1], i); child[fa[j-1]]++; } } void print(People a) { int i = a.lv; while(i--) putchar('.'); cout << a.name << endl; } void List(int t) { print(p[t]); vector<People> q; int r = 0, i; for(i = head[t]; i != -1; i = g[i].next) { q.push_back(p[g[i].to]); r++; } if(r == 0) return ; sort(q.begin(), q.end()); for(i = 0; i < r; ++i) { List(q[i].num); } } char op[2]; void solve() { int q, i, j, pos; scanf("%d", &q); while(q--) { scanf("%s", op); if(op[0] == 'L') { List(0); } else if(op[0] == 'b') { cin >> tmp; i = numb[tmp]; if(i == 0) puts("1"); else printf("%d\n", child[pre[i]]); } else { cin >> tmp >> tmp2; i = numb[tmp]; j = numb[tmp2]; pos = LCA.query(i, j); if(pos == i) pos = pre[i]; if(pos == j) pos = pre[j]; cout << p[pos].name << endl; } } } int main() { //Read(); while(scanf("%d", &n), n) { init(); read_data(); LCA.build(); solve(); } return 0; }
相关文章推荐
- HDU 4409 - Family Name List(模拟树+lca)
- HDU 4409 Family Name List(LCA)
- HDU 4409 Family Name List --乱搞、LCA
- hdu 4409 Family Name List LCA +stl
- Hdu 4409 Family Name List (LCA 家谱 STL 2012金华网赛)
- HDU 4409 Family Name List --乱搞、LCA
- HDU-4409 Family Name List LCA求解,TC+DFS || tarjan
- hdu 4409 Family Name List
- HDU 4409 Family Name List 简单树操作
- hdu 4409 Family Name List
- hdu 4409 Family Name List 金华赛区1010 (解题报告)
- Family Name List (HDU 4409)
- 【模拟】 hdu4409 Family Name List
- HDU 4409 大模拟 + LCA
- ACM网络赛金华赛区的一道关于树的题:Family Name List
- [ACM] HDU 5131 Song Jiang's rank list (模拟)
- hdu 4409 LCA
- HDU 1984 & ZOJ 2987 Misspelling(模拟)
- HDU 1986 & ZOJ 2989 Encoding(模拟)
- hdu 4547 Tarjan LCA 离线算法