UVALive 7291 Kinfolk(最近公共祖先)
题目中的描述就很最近公共祖先,再说其实这个题并不难,就是麻烦点(代码其实可以化简的),我写的判定比较多。
方法;求出两者的最近公共祖先lca,在求出两者到lca的距离
分析:给出a和b,如果LCA(a,b) == a或者b,那他们肯定是直系的,是父子,爷孙之类的关系。
如果LCA(a,b)> a 和 b,假如说a的辈分高(使用深度代表辈分),且disa = 1,那么他们是叔叔,侄子之类的关系
再者就是堂姐堂弟的关系了,代码里解释的比较详细,代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 32767
struct Node
{
int l,r,pa,deep;
} node[N+];
void dfs(int x,int d)
{
if(x > N) return;
node[x].l = x*+;
node[x].r = x*+;
node[x].deep = d;
if(x==) node[x].pa = x;
else if(x%==) node[x].pa = x/-;
else node[x].pa = x/;
dfs(node[x].l,d+);
dfs(node[x].r,d+);
}
int LCA(int a,int b)
{
while(node[a].deep > node[b].deep)
{
a = node[a].pa;
}
while(node[b].deep > node[a].deep)
{
b = node[b].pa;
}
while(a != b)
{
a = node[a].pa;
b = node[b].pa;
}
return a;
}
int main()
{
// freopen("A.in.cpp","r",stdin);
dfs(,);///预处理每一个节点的父亲和深度
int a,b,lca,disa,disb;
string tmp;
char gender;
while(~scanf("%d %d %c",&a,&b,&gender))
{
if(a==- && b==-) break;
lca = LCA(a,b);///求出lca和距离
disa = node[a].deep - node[lca].deep;
disb = node[b].deep - node[lca].deep;
// printf("LCA(%d,%d) = %d\n",a,b,lca);
// printf("lca - deep = %d\n",node[lca].deep);
// printf("disa = %d disb = %d\n",disa,disb);
if(a == b) printf("self\n");
else if(disa == disb && disa == )///姐弟关系
{
if(gender == 'F') printf("sister\n");
else printf("brother\n");
}
else if(lca == a)///直系关系
{
if(gender == 'F') tmp = "daughter";
else tmp = "son";
if(disb == )
cout<<tmp<<endl;
else if(disb == ) cout<<"grand"<<tmp<<endl;
else if(disb == ) cout<<"great-grand"<<tmp<<endl;
else if(disb == ) cout<<"great-great-grand"<<tmp<<endl;
else printf("kin\n");
}
else if(lca == b)
{
if(gender == 'F') tmp = "mother";
else tmp = "father";
if(disa == )
cout<<tmp<<endl;
else if(disa == ) cout<<"grand"<<tmp<<endl;
else if(disa == ) cout<<"great-grand"<<tmp<<endl;
else if(disa == ) cout<<"great-great-grand"<<tmp<<endl;
else printf("kin\n");
}
else if(node[a].pa == lca && node[a].deep < node[b].deep)///叔侄关系
{
if(gender == 'F') tmp = "niece";
else tmp = "nephew";
if(disb == )
cout<<tmp<<endl;
else if(disb == ) cout<<"grand"<<tmp<<endl;
else if(disb == ) cout<<"great-grand"<<tmp<<endl;
else if(disb == ) cout<<"great-great-grand"<<tmp<<endl;
else printf("kin\n");
}
else if(node[b].pa == lca && node[a].deep > node[b].deep)
{
if(gender == 'F') tmp = "aunt";
else tmp = "uncle";
if(disa == )
cout<<tmp<<endl;
else if(disa == ) cout<<"grand"<<tmp<<endl;
else if(disa == ) cout<<"great-grand"<<tmp<<endl;
else if(disa == ) cout<<"great-great-grand"<<tmp<<endl;
else printf("kin\n");
}
else if(disa >= && disb >= )///堂姐堂弟
{
tmp = "cousin";
int Max = max(disa,disb);
int Min = min(disa,disb);
int cha = Max - Min;///这个差帮助我们判定后代
if(Min <= && cha <= )
{
if(Min == ) cout<<"1st "<<tmp;
else if(Min == ) cout<<"2nd "<<tmp;
else if(Min == ) cout<<"3rd "<<tmp;
if(cha == ) cout<<endl;
else if(cha == ) cout<<" once removed"<<endl;
else if(cha == ) cout<<" twice removed"<<endl;
else if(cha == ) cout<<" thrice removed"<<endl;
}
else cout<<"kin"<<endl;
}
else cout<<"kin"<<endl;
}
return ;
}
UVALive 7291 Kinfolk(最近公共祖先)的更多相关文章
- POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)
POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...
- LCA最近公共祖先 ST+RMQ在线算法
对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决. 这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...
- 【转】最近公共祖先(LCA)
基本概念 LCA:树上的最近公共祖先,对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. RMQ:区间最小值查询问题.对于长度为n的 ...
- 【并查集】【树】最近公共祖先LCA-Tarjan算法
最近公共祖先LCA 双链BT 如果每个结点都有一个指针指向它的父结点,于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表.因此这个问题转换为两个单向链表的第一个公共结点(先分别遍历两个链表 ...
- 洛谷P3379 【模板】最近公共祖先(LCA)
P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交 讨论 题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
- 数据结构作业——sights(最短路/最近公共祖先)
sights Description 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点,由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱的小风姑娘不想走那么 ...
- [最近公共祖先] POJ 3728 The merchant
The merchant Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 4556 Accepted: 1576 Desc ...
- [最近公共祖先] POJ 1330 Nearest Common Ancestors
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 27316 Accept ...
随机推荐
- 高精度运算专题1-加法运算(The addition operation)
这个专题呢,我就来讲讲高精度的加法,下面是一个计算加法的函数(用数组a加上数组b结果存到数组c里面). 思路:先测一下数组a和数组b的长度,分别放到a[0].b[0]里面去,再从第二位开始相加,记得满 ...
- 【Loadrunner】初学Loadrunner——参数化设置(Xml类型)
不是所有类型的参数都是和XML类型,只有一段标准的XML语句块,而且需要选中整个完整的XML语句块才可以使用XML的参数化.单个变量是不适合XML的参数化的.在选择的时候需要选中XML语句块的起始标签 ...
- Sublime Text学习笔记
1.快捷键(Key Bindings) Preferences -> Key Bindings ->Default 会打开一个配置文件,里面全是配置信息 2.代码片段(Snippe ...
- E - 小晴天老师系列——我有一个数列!
E - 小晴天老师系列——我有一个数列! Time Limit: 20000/10000MS (Java/Others) Memory Limit: 128000/64000KB (Java/O ...
- sql语句判断两个时间段是否有交集
场景: 数据库有有两个字段.开始时间<startTime>,和结束时间<endTime>,指定一个时间段(a,b),a表示开始时间,b表示结束时间.看数据库中有没有与(a,b ...
- python paramiko模拟ssh登录,实现sftp上传或者下载文件
Python Paramiko模块的安装与使用详解 paramiko是短链接,不是持续链接,只能执行你设定的shell命令,可以加分号执行两次命令. http://www.111cn.net/phpe ...
- 数组按时间(字符串->Date)排序
不说了 ,直接上代码.Talk is cheap , show me the code. NSArray *stortedArray = [wkSelf.dataArray sortedArrayUs ...
- 在自学php的路上不知道怎么走!!
在自学php的路上不知道怎么走!! 真希望有人给我指点一二!!!
- C# 除法的细节
最近在做项目时有个地方用到了概率,要计算概率自然会用到除法.我这边概率的算法是这样的,从0到10000获取个随机数,随机值除以10000就是概率了,但是一时大意没注意细节,结果直接除了,如下: 查询结 ...
- /usr 的由来及/usr目录结
/usr 的由来及/usr目录结构 本文转自Delectat.com讨论中,大部分观点认为: usr 是 unix system resources 的缩写: usr 是 user 的缩写: us ...