ACM PKU 1470 Closest Common Ancestors
//题目描述:http://poj.org/problem?id=1470
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAXN=1009; int size,dep; int N,Q; int box[MAXN],ecnt; int depth[MAXN],c[MAXN],pos[MAXN]; bool flag[MAXN]; int a[20][2*MAXN],ans[MAXN]; struct node { int to,next; } e[MAXN]; void make_map(int from,int to) { e[ecnt].to=to; e[ecnt].next=box[from]; box[from]=ecnt++; } void DFS(int root,int dep) { c[size]=root,depth[size]=dep,pos[root]=size++; for(int i=box[root]; ~i; i=e[i].next) { DFS(e[i].to,dep+1); c[size]=root,depth[size++]=dep; } } void Make_RMQ() { for(int i=0; i<size; i++) { a[0][i]=c[i]; } for(int j=1,k=2; k<size; j++,k<<=1) for(int i=1; i+k-1<size; i++) if(depth[a[j-1][i]]<=depth[a[j-1][i+(k>>1)]]) a[j][i]=a[j-1][i]; else a[j][i]=a[j-1][i+(k>>1)]; } int Query(const int &l,const int &r) { int j=0,k=1; while(k<=r-l+1)j++,k<<=1; j--,k>>=1; if(depth[a[j][l]]<=depth[a[j][r-k+1]]) return a[j][l]; else return a[j][r-k+1]; } int main() { freopen("in.txt","r",stdin); while(scanf("%d",&N)) { ecnt=0,size=1,dep=0; memset(flag,0,sizeof(flag)); memset(depth,0,sizeof(depth)); memset(box,-1,sizeof(box)); memset(pos,0,sizeof(pos)); memset(ans,0,sizeof(ans)); for(int i=0; i<N; i++) { int nod,num; scanf("%d:(%d)",&nod,&num); int tmp; for(int j=0; j<num; j++) { scanf("%d",&tmp); make_map(nod,tmp); flag[tmp]=true; } } int root=1; for(int i=1; i<=N; i++) { if(!flag[i]) { root=i; break; } } DFS(root,dep); // for(int i=1;i<size;i++) // cout<<c[i]<<" "; // cout<<endl; // // for(int i=1;i<size;i++) // cout<<depth[i]<<" "; // cout<<endl; // // for(int i=1;i<=N;i++) // cout<<pos[i]<<" "; // cout<<endl; Make_RMQ(); scanf("%d",&Q); int l,r; for(int i=0; i<Q; i++) { while(getchar()!='('); scanf("%d %d",&l,&r); while(getchar()!=')'); int indexl=pos[l]; int indexr=pos[r]; if(indexl>indexr) swap(indexl,indexr); int index=Query(indexl, indexr); ans[index]++; } for(int i=1; i<=N; i++) { if(ans[i]) printf("%d:%d\n",i,ans[i]); } } return 0; }