Family Name List

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 882    Accepted Submission(s): 271

Problem Description
Kong belongs to a huge family. Recently he got a family name list which lists all men (no women) in his family over many generations. 



The list shows that the whole family has a common ancestor, let's call him Mr. X. Of course, everybody except Mr.X in the list is Mr. X's descendant. Everybody's father is shown in the list except that Mr. X's father is not recorded. We define that Mr. X's
generation number is 0. His son's generation number is 1.His grandson's generation number is 2, and so on. In a word, everybody's generation number is 1 smaller than his son's generation number. Everybody's generation number is marked in some way in the list.



Now Kong is willing to pay a lot of money for a program which can re-arrange the list as he requires ,and answer his questions such as how many brothers does a certain man have, etc. Please write this program for him.
 
Input
There are no more than 15 test cases. 

For each test case:

The first line is an integer N( 1 <= N <= 30,000), indicating the number of names in the list.

The second line is the name of Mr. X.

In the next N-1 lines, there is a man's name in each line. And if the man's generation number is K, there are K dots( '.') before his name.



Please note that :

1) A name consists of only letters or digits( '0'-'9').

2) All names are unique.

3) Every line's length is no more than 60 characters.

4) In the list, a man M's father is the closest one above M whose generation number is 1 less than M.

5) For any 2 adjacent lines in the list, if the above line's generation number is G1 and the lower line' s generation number is G2, than G2 <= G1 +1 is guaranteed. 



After the name list, a line containing an integer Q(1<=Q<=30,000) follows, meaning that there are Q queries or operations below.



In the Next Q lines, each line indicates a query or operation. It can be in the following 3 formats:

1) L

Print the family list in the same format as the input, but in a sorted way. The sorted way means that: if A and B are brothers(cousins don’t count), and A's name is alphabetically smaller than B's name, then A must appear earlier than B. 

2) b name

Print out how many brothers does "name" have, including "name" himself.

3) c name1 name2

Print out the closest common ancestor of "name1" and "name2". "Closest" means the generation number is the largest. Since Mr. X has no ancestor in the list, so it's guaranteed that there is no question asking about Mr. X's ancestor. 



The input ends with N = 0.
 
Output
Already mentioned in the input.
 
Sample Input
9
Kongs
.son1
..son1son2
..son1son1
...sonkson2son1
...son1son2son2
..son1son3
...son1son3son1
.son0
7
L
b son1son3son1
b son1son2
b sonkson2son1
b son1
c sonkson2son1 son1son2son2
c son1son3son1 son1son2
0
 
Sample Output
Kongs
.son0
.son1
..son1son1
...son1son2son2
...sonkson2son1
..son1son2
..son1son3
...son1son3son1
1
3
2
2
son1son1
son1
 
Source
 
Recommend
 
题意:
给你一棵树。

有三种操作。

1.输出树的dfs序。

字典序小的先输出。

2.输出一个结点的父亲有多少儿子。包含自己。
3.输出u,v的LCA。

思路:
这题输入比較蛋疼。我是用一个栈来建树的。

不知道有其他什么高级方法没。

然后对于操作1.因为要字典序小的的先dfs。那么仅仅好用 不是非常熟悉的vector存边了。然后对边按名字字典序排序。

然后dfs一次把答案存起来。对于2记录下一个结点的父亲是谁即可了。

对于3.tarjan离线处理。这题有个坑点就是LCA不能是自己。over。

具体见代码:
#include<cstdio>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int maxn=30010;
int cnt,ptr,pp,vis[maxn],ty[maxn],aans[maxn];
int st[maxn],rk[maxn],fa[maxn],pa[maxn],uu[maxn],vv[maxn];
char na[100];
vector<int> G[maxn];
string name[maxn],ans[maxn];
map<string,int> mp;
struct node
{
int v,id;
node *next;
} ed[maxn<<1],*head[maxn];
void adde(int u,int v,int id)
{
ed[ptr].v=v;
ed[ptr].id=id;
ed[ptr].next=head[u];
head[u]=&ed[ptr++];
}
bool cmp(int a,int b)
{
return name[a]<name[b];
}
void dfs(int u)
{
string op=".";
ans[pp]="";
for(int i=0;i<rk[u];i++)
ans[pp]+=op;
ans[pp++]+=name[u];
for(int i=0;i<G[u].size();i++)
{
pa[G[u][i]]=u;
dfs(G[u][i]);
}
}
int getfa(int x)
{
if(fa[x]==x)
return x;
return fa[x]=getfa(fa[x]);
}
void tarjan(int u)
{
vis[u]=1,fa[u]=u;
for(node *p=head[u];p!=NULL;p=p->next)
{
if(vis[p->v])
aans[p->id]=getfa(p->v);
}
for(int i=0;i<G[u].size();i++)
{
tarjan(G[u][i]);
fa[G[u][i]]=u;
}
}
int main()
{
int i,j,n,m,tp,ct,id,u,v;
string aa,bb;
char cmd[20]; while(scanf("%d",&n),n)
{
for(i=0;i<=n;i++)
G[i].clear();
mp.clear();
tp=cnt=1;
st[0]=0,rk[0]=-1;
for(i=0;i<n;i++)
{
scanf("%s",na);
ct=0;
for(j=0;na[j];j++)
if(na[j]=='.')
ct++;
else
break;
string nna(na+ct);
//cout<<nna<<endl;
if(!mp.count(nna))
{
name[cnt]=nna;
rk[cnt]=ct;
mp[nna]=cnt++;
}
id=mp[nna];
while(rk[st[tp-1]]>=rk[id])
tp--;
G[st[tp-1]].push_back(id);
st[tp++]=id;
}
for(i=1;i<=n;i++)
sort(G[i].begin(),G[i].end(),cmp);
pp=0;
dfs(1);
ptr=0;
memset(head,0,sizeof head);
memset(vis,0,sizeof vis);
scanf("%d",&m);
for(i=0;i<m;i++)
{
scanf("%s",cmd);
if(cmd[0]=='L')
ty[i]=0;
else if(cmd[0]=='b')
{
ty[i]=1;
cin>>aa;
id=mp[aa];
aans[i]=G[pa[id]].size();
}
else
{
ty[i]=2;
cin>>aa>>bb;
u=mp[aa],v=mp[bb];
uu[i]=u,vv[i]=v;
adde(u,v,i);
adde(v,u,i);
}
}
tarjan(1);
for(i=0;i<m;i++)
{
if(ty[i]==0)
{
for(j=0;j<n;j++)
cout<<ans[j]<<endl;
}
else if(ty[i]==1)
printf("%d\n",aans[i]);
else
{
if(aans[i]==uu[i]||aans[i]==vv[i])
aans[i]=pa[aans[i]];
cout<<name[aans[i]]<<endl;
}
}
}
return 0;
}

hdu 4409 Family Name List(LCA&amp;有坑点)的更多相关文章

  1. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  2. hdu 6203 ping ping ping(LCA+树状数组)

    hdu 6203 ping ping ping(LCA+树状数组) 题意:给一棵树,有m条路径,问至少删除多少个点使得这些路径都不连通 \(1 <= n <= 1e4\) \(1 < ...

  3. HDU 4409 Family Name List --乱搞、LCA

    题意: 给出一些名字,名字间有父子关系,有三种操作: 1.按祖先到后代,兄弟间按字典序由小到大排序,然后输出 2.求某个节点的兄弟节点有多少个,包括自己(注意,根节点的兄弟节点是1) 3.求节点a和b ...

  4. hdu 4409 LCA

    思路:就是个比较裸的LCA了,不过要注意的是,如果a和b的公共祖先是a,那么答案就是farther[a]. #include<cstring> #include<cmath> ...

  5. HDU 3078:Network(LCA之tarjan)

    http://acm.hdu.edu.cn/showproblem.php?pid=3078 题意:给出n个点n-1条边m个询问,每个点有个权值,询问中有k,u,v,当k = 0的情况是将u的权值修改 ...

  6. HDU 2874 Connections between cities (LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意是给你n个点,m条边(无向),q个询问.接下来m行,每行两个点一个边权,而且这个图不能有环路 ...

  7. 【HDU 4547 CD操作】LCA问题 Tarjan算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4547 题意:模拟DOS下的cd命令,给出n个节点的目录树以及m次查询,每个查询包含一个当前目录cur和 ...

  8. HDU 5452 Minimum Cut(LCA)

    http://acm.hdu.edu.cn/showproblem.php?pid=5452 题意: 有一个连通的图G,先给出图中的一棵生成树,然后接着给出图中剩余的边,现在要删除最少的边使得G不连通 ...

  9. HDU 2460 Network(桥+LCA)

    http://acm.hdu.edu.cn/showproblem.php?pid=2460 题意:给出图,求每次增加一条边后图中桥的数量. 思路: 先用tarjan算法找出图中所有的桥,如果lowv ...

随机推荐

  1. Lombok 使用小结

    Lombok 简介 Lombok 是一种 Java 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO).它通过注释实现这一目的.通过在开发环境中实现 Lo ...

  2. 如何兼容所有Android版本选择照片或拍照然后裁剪图片--基于FileProvider和动态权限的实现

    我们知道, Android操作系统一直在进化. 虽然说系统是越来越安全, 可靠, 但是对于开发者而言, 开发难度是越来越大的, 需要注意的兼容性问题, 也越来越多. 就比如在Android平台上拍照或 ...

  3. ldap数据库--ODSEE--安装

    在安装之前最好查看一下服务器硬件是否满足要求,是否需要更改一些系统配置来达到使用ldap数据库的最有性能.实际使用的ldap数据库是oracle的产品,DS70即ODSEE. 安装环境:solaris ...

  4. centos6.5安装rabbitmq3.6.14

    The minimum version of Erlang/OTP required to run RabbitMQ server 3.6.0 through 3.6.14 is R16B03. St ...

  5. C#中抽象类和接口的区别2

    1.接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性        抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性:       2. 下面分别从声明, ...

  6. pt-show-grants

    用法: pt-show-grants [OPTION ... ] [DSN]   例子: pt-show-grants pt-show-grants --separate --revoke | dif ...

  7. JAVA提高十三:Hashtable&Properties深入分析

    最近因为一些琐碎的事情,导致一直没时间写博客,正好今天需求开发完的早,所以趁早写下本文,本文主要学习的是Hashtable的分析,因为上面一篇文章研究的是HashMap,而Hashtable和Hash ...

  8. JavaScript学习笔记(六)——Map、Set与iterable

    在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...

  9. 父类清除浮动的原因、(清除浮动代码,置于CSS中方便调用)

    浮动因素在静态网页制作中经常被应用到,比如要让块级元素不独占一行,常常应用设置float的方式来实现.但是应用的时候会发现,设置了子类浮动后,未给父类清除浮动,这样就会造成一下问题: 1.浮动的元素会 ...

  10. app打包常用操作

    1.修改appId android:打开build.gradle文件 找到defaultConfig{applicationId 'ceshi'} 修改测试.android studio会提示. Gr ...