hdu 4409 LCA
2013-08-20 13:55
316 查看
思路:就是个比较裸的LCA了,不过要注意的是,如果a和b的公共祖先是a,那么答案就是farther[a]。
#include<cstring> #include<cmath> #include<vector> #include<algorithm> #include<map> #include<string> #include<iostream> #include<cstdio> #define Maxn 300010 using namespace std; int vi[Maxn],pre[Maxn]; int dep[Maxn],sec[Maxn],farther[Maxn]; int e,Md; char str[Maxn][70],ans[Maxn][70]; vector<int> head[Maxn]; map< string,int> g; void init() { Md=0; memset(pre,0,sizeof(pre)); memset(vi,0,sizeof(vi)); memset(dep,0,sizeof(dep)); memset(farther,0,sizeof(farther)); memset(sec,0,sizeof(sec)); for(int i=0;i<=300000;i++) head[i].clear(); g.clear(); } void add(int u,int v) { head[u].push_back(v); } void dfs(int u) { int i,j,now,sz; sz=head[u].size(); for(i=0;i<sz;i++) { now=head[u][i]; dep[now]=dep[u]+1; farther[now]=u; dfs(now); } Md=max(Md,dep[u]); } void make_sec(int u) { int i,j,now,sz; if(dep[u]<Md) { sec[u]=0; } else { if(dep[u]%Md==0) sec[u]=farther[u]; else sec[u]=sec[farther[u]]; } sz=head[u].size(); for(i=0;i<sz;i++) { now=head[u][i]; make_sec(now); } } int LCA(int a,int b) { int x=a,y=b; while(sec[a]!=sec[b]) { if(dep[a]>dep[b]) a=sec[a]; else b=sec[b]; } while(a!=b) { if(dep[a]>dep[b]) a=farther[a]; else b=farther[b]; } return a; } int cmp(int a,int b) { return strcmp(ans[a],ans[b])<0; } void dfssort(int u) { int i,v,sz; sz=head[u].size(); sort(head[u].begin(),head[u].end(),cmp); for(i=0;i<sz;i++) { dfssort(head[u][i]); } } void Out(int u) { int i,v,sz; printf("%s\n",str[u]); sz=head[u].size(); for(i=0;i<sz;i++) { v=head[u][i]; Out(v); } } int main() { int n,i,j,cnt,q; char cc[70]; while(scanf("%d",&n)!=EOF,n) { init(); scanf("%s",str[0]); strcpy(ans[0],str[0]); g[str[0]]=0; pre[0]=0; for(i=1;i<n;i++) { scanf("%s",str[i]); j=0; cnt=0; while(str[i][j]=='.') { cnt++; j++; } int pos=0; while(str[i][j]!='\0') { cc[pos++]=str[i][j]; j++; } cc[pos]='\0'; g[cc]=i; strcpy(ans[i],cc); add(pre[cnt-1],i); pre[cnt]=i; } dfssort(0); dfs(0); Md=sqrt(1.0*Md); make_sec(0); scanf("%d",&q); for(i=1;i<=q;i++) { scanf("%s",cc); if(cc[0]=='L') { Out(0); } else if(cc[0]=='b') { scanf("%s",cc); int v=g[cc]; printf("%d\n",head[farther[v]].size()); } else if(cc[0]=='c') { char s1[70],s2[70]; scanf("%s%s",s1,s2); int u=g[s1]; int v=g[s2]; int ff=LCA(u,v); if(ff==u) { printf("%s\n",ans[farther[u]]); } else if(ff==v) { printf("%s\n",ans[farther[v]]); } else printf("%s\n",ans[ff]); } } } return 0; }
相关文章推荐
- HDU 4409 大模拟 + LCA
- HDU 4409 - Family Name List(模拟树+lca)
- HDU-4409 Family Name List LCA求解,TC+DFS || tarjan
- HDU 4409 Family Name List --乱搞、LCA
- Hdu 4409 Family Name List (LCA 家谱 STL 2012金华网赛)
- 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 2586 How far away ?(在线LCA+离线Tarjan)
- hdu 2874 Connections between cities(st&rmq LCA)
- HDU 6162 主席树+LCA(树上求区间[a,b]中的个数)
- hdu 2586 How far away ? 最近公共祖先lca 在线算法(倍增法)/离线算法(Tarjan算法)
- HDU_2586 && HDU_2874 (LCA+tarjan)
- HDU 2874 LCA转RMQ裸题
- hdu 3830 二分+LCA
- hdu 5296 Annoying problem (LCA)
- hdu 2586 How far away ? 【图论-邻接表-图转树-Lca】
- HDU 2586 How far away ? LCA离线tarjan思想
- hdu 4547(LCA)