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

  方法;求出两者的最近公共祖先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. 与malloc有关的问题

    nefu 1026 申请动态空间存放字符串,将其排序后输出 http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1026 #in ...

  2. 第三次冲刺spring会议(第一次会议)

    [例会时间]2014/5/20 21:15 [例会地点]9#446 [例会形式]轮流发言 [例会主持]马翔 [例会记录]兰梦 小组成员:兰梦 ,马翔,李金吉,赵天,胡佳

  3. 对象比较中 "相等性"和"同一性" 生动地解释

    对象们都住在不同的房间里,每个房间只能住一个对象.对象们都被锁在房间里,永远没有办法搬家(至少从我们讨论的角度来说,这个说法是正确的).所以如果你知道了一个对象的房间号,就能找到对应的对象. 现在假如 ...

  4. Android RIL Log

    转载: 要调试 RIL,最好的方法就是打开 radio的log: $ adb logcat -b radio 最好加上 log语法亮度工具coloredlogcat.py ,一些常见的LOG TAG要 ...

  5. 27.编写一个Animal类,具有属性:种类;具有功能:吃、睡。定义其子类Fish 和Dog,定义主类E,在其main方法中分别创建其对象并测试对象的特性。

    ///Animal类 package d922A; public class Animal { private String kind; public String getKind() { Syste ...

  6. img转data

    http://blog.csdn.net/lwjok2007/article/details/50756273

  7. mongoDB7--游标cursor

    之前我们学习了"增删改查"四中语法和查询表达式的深入学习,我们已经掌握了一定的操作mongodb数据的能力,那么接下来我们就要考虑我们的操作的效率问题了.(1)游标介绍如果我们查询 ...

  8. 河南多校联合训练 南阳理工 1261 音痴又音痴的LT

    描述 LT最近一直在无限循环薛之谦的歌,简直都中毒了!可是呢…他的歌LT还是不会唱(其实不止他的歌LT不会唱,所有人的歌LT都不会唱…因为LT是标准的音痴)可是LT又很喜欢唱歌(所以LT不仅是音痴还是 ...

  9. ios随机数

    ios 随机数生成 字数612 阅读3037 评论1 喜欢15 最近一直使用随机数,为了以后方便查阅,总结一下: 在C中提供了rand().srand().random().arc4random()几 ...

  10. ASP.NET弹出提示点击确定之后再跳转页面的方法

    //ASP.NET弹出提示点击确定之后再跳转页面的方法 //弹出了提示并且通过location.href转到了DeskTop.aspx页面 Response.Write("<scrip ...