2012 2012 ACM/ICPC Asia Regional Jinhua Online Family Name List
http://acm.hdu.edu.cn/showproblem.php?pid=4409
思路:建树后,就是裸LCA了,代码写得不好~~~

#include<stdio.h> #include<string.h> #include<string> #include<vector> #include<iostream> #include<algorithm> #include<map> using namespace std; const int maxn = 30003; int fa[maxn],pre[maxn]; map<string,int>ds; vector<int>as[maxn]; vector<int>qes[maxn]; vector<int>idd[maxn]; char cs[maxn][100]; int tmp[maxn]; int n,m,cnt; int ans[maxn],vis[maxn]; struct nd { char op; int a,b; }ask[maxn]; int f[maxn],anc[maxn]; int fin(int x){if(x!=f[x])f[x]=fin(f[x]);return f[x];} bool cmp(int a,int b) { return strcmp(cs[a],cs[b])<0; } void Sort(int x) { int i,j; for(i = 0; i < as[x].size(); ++ i) Sort(as[x][i]); if(i>1){ for(i = 0; i < as[x].size(); ++ i) tmp[i]=as[x][i]; sort(tmp,tmp+i,cmp); for(j = 0; j < i; ++ j) as[x][j]=tmp[j]; } } void DFS(int x) { int i; puts(cs[x]); for(i = 0; i < as[x].size(); ++ i) { DFS(as[x][i]); } } void LCA(int u) { int i,v; anc[u]=u; for(i = 0; i < as[u].size(); ++ i){ v = as[u][i]; LCA(v); int x = fin(u); int y = fin(v); if(x^y)f[x]=y; anc[fin(u)] = u; } vis[u]=1; for(i = 0; i < qes[u].size(); ++ i) if(vis[qes[u][i]]){ ans[idd[u][i]]=anc[fin(qes[u][i])]; } } void readin() { char s[100],ss[100]; int i,k,j; for(i=0; i <= n; ++ i) {as[i].clear();qes[i].clear();idd[i].clear();} cnt = 0; ds.clear(); for(i = 0; i < n; ++ i){ scanf("%s",s); for(j = 0; s[j]=='.'; ++ j); strcpy(cs[cnt],s); ds[string(s+j)] = cnt; fa[cnt] = j?pre[j-1]:0; if(cnt)as[fa[cnt]].push_back(cnt); pre[j] = cnt++; } Sort(0); scanf("%d",&m); for(i = 0; i < m; ++ i){ scanf("%s",s); ask[i].op = s[0]; if(s[0]=='L')continue; if(s[0]=='b'){ scanf("%s",ss); ask[i].a = ds[ss]; } if(s[0]=='c'){ scanf("%s%s",s,ss); int a = ds[s]; int b = ds[ss]; ask[i].a = a; ask[i].b = b; qes[a].push_back(b); qes[b].push_back(a); idd[a].push_back(i); idd[b].push_back(i); } } for(i = 0; i <= n; ++ i)f[i]=i; memset(vis,0,sizeof(vis)); LCA(0); } void processing() { int i,j,k; char s[100]; for(i = 0; i < m; ++ i) { if(ask[i].op=='L')DFS(0); if(ask[i].op=='b'){ k = ask[i].a; printf("%d\n",as[fa[k]].size()); } if(ask[i].op=='c'){ k = ans[i]; if(k==ask[i].a || k==ask[i].b) k = fa[k]; strcpy(s,cs[k]); for(j = 0; s[j]=='.'; ++ j); puts(s+j); } } } int main() { while(scanf("%d",&n)==1) { if(!n)break; readin(); // puts("IN"); processing(); } return 0; }