HDU 4409 Family Name List(LCA)
2012-10-05 20:25
465 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4409
题意:给定一个家谱。有三种询问:
(1)L重新打印家谱,同一代的人按照升序;
(2)b name 输出name的亲兄弟有多少个?
(3)c name1 name2输出name1和name2 的最近公共祖先。
注意(3):如果最近公共祖先是name1或者name2,那么要输出其父亲。(因为自己不能是自己的祖先。。)
思路:建图的时候就按照正常的建,但是输出的时候将同一个父亲的孩子排序输出(2)在DFS的时候顺便统计一下;(3)就是LCA。
题意:给定一个家谱。有三种询问:
(1)L重新打印家谱,同一代的人按照升序;
(2)b name 输出name的亲兄弟有多少个?
(3)c name1 name2输出name1和name2 的最近公共祖先。
注意(3):如果最近公共祖先是name1或者name2,那么要输出其父亲。(因为自己不能是自己的祖先。。)
思路:建图的时候就按照正常的建,但是输出的时候将同一个父亲的孩子排序输出(2)在DFS的时候顺便统计一下;(3)就是LCA。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MAX=30005; //节点数量 struct node { int v,next; }; struct Node { char s[65]; int id; }; int cmp(Node a,Node b) { return strcmp(a.s,b.s)<0; } node edges[MAX<<1]; int head[MAX],e; int pre[MAX],dep[MAX]; int id[MAX]; //节点第一次被遍历的顺序 int RMQ[MAX*3][20]; int curID; //F[i]表示第i个遍历的节点 //B[i]表示F[i]在树中的深度 int F[MAX*3],B[MAX*3]; int father[MAX],d[MAX]; int ID; Node hash[MAX],hash1[MAX]; int add(char str[]) { ID++; strcpy(hash[ID].s,str); hash[ID].id=ID; return ID; } int getID(char str[]) { int low=1,high=ID,mid; while(low<=high) { mid=(low+high)>>1; if(strcmp(hash[mid].s,str)==0) break; if(strcmp(hash[mid].s,str)<0) low=mid+1; else high=mid-1; } return hash[mid].id; } void init() { curID=0; ID=0; memset(head,-1,sizeof(head)); e=0; } void Add(int u,int v) { edges[e].v=v; edges[e].next=head[u]; head[u]=e++; } int sonNum[MAX]; void DFS(int u,int p,int Dep) { int i,v; curID++; F[curID]=u; B[curID]=Dep; id[u]=curID; pre[u]=p; dep[u]=Dep; sonNum[u]=0; for(i=head[u];i!=-1;i=edges[i].next) { v=edges[i].v; if(v==p) continue; DFS(v,u,Dep+1); curID++; F[curID]=u; B[curID]=Dep; sonNum[u]++; } } void initRMQ() { int i,j,x,y; for(i=1;i<=curID;i++) RMQ[i][0]=i; for(j=1;(1<<j)<=curID;j++) for(i=1;i+(1<<j)-1<=curID;i++) { x=RMQ[i][j-1]; y=RMQ[i+(1<<(j-1))][j-1]; RMQ[i][j]=B[x]<B[y]?x:y; } } int getLCA(int a,int b) { int k,x,y; a=id[a];b=id[b]; if(a>b) k=a,a=b,b=k; k=log(1.0+b-a)/log(2.0); x=RMQ[a][k]; y=RMQ[b-(1<<k)+1][k]; return B[x]<B[y]?F[x]:F[y]; } void build(int n) { char str[65]; int i,j,k,u,v; scanf("%s",str); u=add(str); d[u]=0;father[u]=-1; for(i=2;i<=n;i++) { scanf("%s",str); for(j=0;str[j]=='.';j++); for(k=j;str[k];k++) str[k-j]=str[k]; str[k-j]='\0'; v=add(str); d[v]=j; while(d[u]+1!=d[v]) u=father[u]; Add(u,v); father[v]=u; u=v; } } int temp[MAX],start[MAX],size[MAX]; void print(int u,int dep) { int i,j,v; for(i=1;i<=dep;i++) putchar('.'); printf("%s\n",hash1[u].s); for(i=start[u];i<start[u]+size[u];i++) { j=temp[i]; v=edges[j].v; print(v,dep+1); } } int cmp1(int a,int b) { int v1=edges[a].v; int v2=edges[b].v; return strcmp(hash1[v1].s,hash1[v2].s)<0; } void deal(int Q) { char cmd[5],str[65],str1[65]; int i,j,u,v; for(i=1;i<=ID;i++) hash1[i]=hash[i]; sort(hash+1,hash+ID+1,cmp); u=1; for(i=1;i<=ID;i++) { size[i]=0; start[i]=u; for(j=head[i];j!=-1;j=edges[j].next) { temp[u]=j; size[i]++; u++; } if(size[i]) { sort(temp+start[i],temp+start[i]+size[i],cmp1); } } while(Q--) { scanf("%s",cmd); if(cmd[0]=='L') { print(1,0); } else if(cmd[0]=='b') { scanf("%s",str); u=getID(str); if(father[u]==-1) puts("1"); else printf("%d\n",sonNum[father[u]]); } else if(cmd[0]=='c') { scanf("%s%s",str,str1); u=getID(str); v=getID(str1); i=getLCA(u,v); if(i==u||i==v) i=father[i]; printf("%s\n",hash1[i].s); } } } int n,Q; int main() { while(scanf("%d",&n),n) { init(); build(n); DFS(1,0,0); initRMQ(); scanf("%d",&Q); deal(Q); } return 0; }
相关文章推荐
- 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
- HDU-4409 Family Name List LCA求解,TC+DFS || tarjan
- Hdu 4409 Family Name List (LCA 家谱 STL 2012金华网赛)
- HDU 4409 - Family Name List(模拟树+lca)
- Family Name List (HDU 4409)
- HDU 4409 Family Name List 简单树操作
- hdu 4409 Family Name List 金华赛区1010 (解题报告)
- hdu 4409 Family Name List
- hdu 4409 Family Name List
- HDU 4409 大模拟 + LCA
- ACM网络赛金华赛区的一道关于树的题:Family Name List
- 【模拟】 hdu4409 Family Name List
- hdu 4409 LCA
- A List of Pages a Peoplesoft Role Name can Access
- how to list tabes based on column name in sybase?
- HDU 1671 Phone List(Trie)
- hdu 1671 Phone List Trie 基础模板