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 ...
随机推荐
- LeetCode OJ 122. Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i. Design an al ...
- Openjudge-计算概论(A)-角谷猜想
描述: 所谓角谷猜想,是指对于任意一个正整数,如果是奇数,则乘3加1,如果是偶数,则除以2,得到的结果再按照上述规则重复处理,最终总能够得到1.如,假定初始整数为5,计算过程分别为16.8.4.2.1 ...
- UILabel 的属性设置
.设置字体样式(加粗) label.font = [UIFont boldSystemFontOfSize:30]; 6.设置字体类型 label.font = [UIFont fontWithNam ...
- c/c++常用的几个关键字总结
一.volatile volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编 ...
- erlang四大behaviour之四-supervisor
http://www.cnblogs.com/puputu/articles/1689621.html 1. 监督规则 一个监督者负责启动.停止.监控他的子进程.监督者的一个基本概念就是当必要的时候重 ...
- Objective-C中关于请求返回NSData数据解析成NSDictionary或NSArray的方法
1.如果后台返回的是字典或数组的data型,直接使用以下方法转换: { // Data 转成 字典 其中responseObject为返回的data数据 NSDictionary *resultDic ...
- jquery-选择checkbox的多种策略
checkbox属性: var val = $("#checkAll").val();// 获取指定id的复选框的值 var isSelected = $("#check ...
- HTML中加载flash方法
首先贴上代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <t ...
- HDU1577-WisKey的眼神
Problem Description WisKey的眼镜有500多度,所以眼神不大好,而且他有个习惯,就是走路喜欢看着地(不是为了拣钱哦^_^),所以大家下次碰见他的时候最好主动打下招呼,呵呵.但是 ...
- IntelliJ IDEA 部署远程服务
今天产品遇到个本地无法重现,服务器上却出现的 Bug. 想起来 IDEA 有远程调试的功能就拿来用用. 教程如下: 1. 创建 tomcat service 2. 填入服务器的 IP 和端口 3. 确 ...