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

  方法;求出两者的最近公共祖先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. [ An Ac a Day ^_^ ] CodeForces 680A Bear and Five Cards

    这两天回家了 家里电脑太卡 调试不方便 就只能写写水题了…… #include<stdio.h> #include<iostream> #include<algorith ...

  2. $pull

    $pull 删除所有匹配的文档,不仅仅只是删除一个. db.test.insert( {"todo":["dishes","laundry" ...

  3. A - LCM Challenge

    A - LCM Challenge Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Others ...

  4. 【Machine Learning in Action --4】朴素贝叶斯从个人广告中获取区域倾向

    背景:广告商往往想知道关于一个人的一些特定人口统计信息,以便能更好地定向推销广告. 我们将分别从美国的两个城市中选取一些人,通过分析这些人发布的信息,来比较这两个城市的人们在广告用词上是否不同.如果结 ...

  5. unity 退到桌面的 OnApplicationPause

    void OnApplicationFocus( bool isFocus ) { // Debug.Log("--------OnApplicationPause---" + i ...

  6. POJ 1696 Space Ant 极角排序(叉积的应用)

    题目大意:给出n个点的编号和坐标,按逆时针方向连接着n个点,按连接的先后顺序输出每个点的编号. 题目思路:Cross(a,b)表示a,b的叉积,若小于0:a在b的逆时针方向,若大于0a在b的顺时针方向 ...

  7. php 图像处理类

    <?php/** file: image.class.php 类名为Image 图像处理类,可以完成对各种类型的图像进行缩放.加图片水印和剪裁的操作. http://www.lai18.com ...

  8. android 按钮Button单击背景切换

    res/drawable/btn_selected.xml <?xml version="1.0" encoding="utf-8"?> <s ...

  9. Java 处理图片 base64 编码的相互转换

    哈喽大家好我是刘德华. 今天项目优化了一下上传头像的功能.采用 imagecropper 插件完成裁剪图片的效果. 这个插件裁剪完的图片都是 base64 加密的字符串,上传头像也就涉及到了如何把加密 ...

  10. how to use the curses library in unix?

    In linux, you can use the ncurses library to use the terminal as a text buffer: move the cursor arou ...