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. Spring IOC容器分析(3) -- DefaultListableBeanFactory

    上一节介绍了封装bean对象的BeanDefinition接口.从前面小结对BeanFactory的介绍中,我们知道bean对象是存储在map中,通过调用getBean方法可以得到bean对象.在接口 ...

  2. spring+struts2+hibernate整合

    web.xml需要配置 <context-param> <param-name>contextConfigLocation</param-name> <par ...

  3. python基础阶段 经典练习题 拾英札记(2)

    因为编程的练习题是交互式的,在不断调试和不断渐进完善中,你会有一种成就感和快乐感,不断的修缮,不断的尝试. 其实,认知自己,和探索世界,也是这样的啊. 只要不放弃,要坚持. #7  根据列表lt,实现 ...

  4. [转载] Java线程池框架源码分析

    转载自http://www.linuxidc.com/Linux/2014-11/108791.htm 相关类Executor,Executors,AbstractExecutorService,Ex ...

  5. Python基础---python中的异常处理

    Python中的异常处理 一.什么是异常处理 python解释器检测到错误,触发异常(也允许程序员自己触发异常) 程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关) ...

  6. RabbitMQ之路由

    为了实现一个新功能:只订阅消息的一个子集,例如只需要把严重的错误日志信息写入日志文件(存储到磁盘上),但同时仍然把所有的日志信息输出到控制台中. 绑定(Bindings) 创建绑定 channel.q ...

  7. shopxx--权限功能测试

    shiro权限控制 一.添加角色 1.打开   系统→角色管理,点击 添加 赋予当前角色对应的权限 二.添加管理员(即用户管理) 添加用户,赋予刚才添加的角色 三.用新用户登录,进行测试 登录结果

  8. Windows server2012如何运行Javaweb项目?

    最近用java写了个小项目,想要部署到服务器,于是买了个Windows server2012,但是不知道怎么部署,后来才知道需要配置java运行环境.经过一番研究最终搞定了.下边是我的个人总结,由于是 ...

  9. mysql数据库表卡死解决方法

    ---恢复内容开始--- 问题引起原因: 由于在执行大量插入操作的时候意外终止程序之后, MySQl的线程并没有被终止,导致表不能打开和操作 -  解决思路就是找到等待的线程并kill -- 查看所有 ...

  10. 《java.util.concurrent 包源码阅读》26 Fork/Join框架之Join

    接下来看看调用ForkJoinTask的join方法都发生了什么: public final V join() { // doJoin方法返回该任务的状态,状态值有三种: // NORMAL, CAN ...