您的位置:首页 > 其它

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

//#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: