题目中的描述就很最近公共祖先,再说其实这个题并不难,就是麻烦点(代码其实可以化简的),我写的判定比较多。

  方法;求出两者的最近公共祖先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(最近公共祖先)的更多相关文章

  1. POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA)

    POJ 1330 Nearest Common Ancestors / UVALive 2525 Nearest Common Ancestors (最近公共祖先LCA) Description A ...

  2. LCA最近公共祖先 ST+RMQ在线算法

    对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决.     这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...

  3. 【转】最近公共祖先(LCA)

    基本概念 LCA:树上的最近公共祖先,对于有根树T的两个结点u.v,最近公共祖先LCA(T,u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. RMQ:区间最小值查询问题.对于长度为n的 ...

  4. 【并查集】【树】最近公共祖先LCA-Tarjan算法

    最近公共祖先LCA 双链BT 如果每个结点都有一个指针指向它的父结点,于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表.因此这个问题转换为两个单向链表的第一个公共结点(先分别遍历两个链表 ...

  5. 洛谷P3379 【模板】最近公共祖先(LCA)

    P3379 [模板]最近公共祖先(LCA) 152通过 532提交 题目提供者HansBug 标签 难度普及+/提高 提交  讨论  题解 最新讨论 为什么还是超时.... 倍增怎么70!!题解好像有 ...

  6. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

  7. 数据结构作业——sights(最短路/最近公共祖先)

    sights Description 美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点,由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱的小风姑娘不想走那么 ...

  8. [最近公共祖先] POJ 3728 The merchant

    The merchant Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 4556   Accepted: 1576 Desc ...

  9. [最近公共祖先] POJ 1330 Nearest Common Ancestors

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 27316   Accept ...

随机推荐

  1. Leetcode016 3Sum Closest

    public class S016 { //借鉴S015的思想,只是稍微有点慢 public int threeSumClosest(int[] nums, int target) { Arrays. ...

  2. NOIP2010-普及组复赛模拟试题-第二题-数字积木

    题目描述 Description 小明有一款新式积木,每个积木上都有一个数,一天小明突发奇想,要是把所有的积木排成一排,所形成的数目最大是多少呢?你的任务就是读入 n 个数字积木,求出所能形成的最大数 ...

  3. mysql高级查询

    高级查询: 1.连接查询 select * from Info,Nation #得出的结果称为笛卡尔积select * from Info,Nation where Info.Nation = Nat ...

  4. 第一题 (Map)利用Map,完成下面的功能:

    从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队.如果该 年没有举办世界杯,则输出:没有举办世界杯.  附:世界杯冠军以及对应的夺冠年份,请参考本章附录. 附录  1.历届世界杯冠 ...

  5. Tennis Championship

    Tennis Championship time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  6. zstu 4215 多起点bfs

    input n m  1<=n,m<=1000 n*m的地图,全为大写字母 7 10 WWWWWCCDEW WWWWCCEEEW WTWWWCCCCW WWFFFFFFWW WWFAAAA ...

  7. spring框架--IOC容器,依赖注入

    思考: 1. 对象创建创建能否写死? 2. 对象创建细节 对象数量 action  多个   [维护成员变量] service 一个   [不需要维护公共变量] dao     一个   [不需要维护 ...

  8. CSS传统布局之页面布局实例

    传统的页面布局依赖于盒模型+流动模型(flow)+浮动模型(float)+层模型(layer)来实现页面的布局,具体方法是通过盒模型+display属性+float属性+position属性来加以实现 ...

  9. mybatis----增删改查

    转: select使用 : xml代码: <!-- 查询学生,根据id --> <select id="getStudent" parameterType=&qu ...

  10. 字符串匹配之boyer-Moore算法

    Boyer-Moore算法不仅效率高,而且构思巧妙,容易理解.1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了这种算法. 下面,我根据Moore ...