[ 题解 ] [ 最小公共父节点 ] E. Family Tree

Posted kaidora

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ 题解 ] [ 最小公共父节点 ] E. Family Tree相关的知识,希望对你有一定的参考价值。

http://codeforces.com/group/NVaJtLaLjS/contest/238202/problem/E


题意:

输入数字N,还有两只牛的名字;

输入N行父子关系(题中为母女)即两个名字,前者是父,后者是子;

问两只牛是什么亲属关系。


具体的输出规则(亲属关系)请见原题。


示例:

Input 

7 AA BB
MOTHER AA
GGMOTHER BB
MOTHER SISTER
GMOTHER MOTHER
GMOTHER AUNT
AUNT COUSIN
GGMOTHER GMOTHER

Output

BB is the great-aunt of AA


求最小公共父节点,看题目的示意图都能猜出来。

这里用C++string变量好很多,我用strcmp比较,strcpy赋值/返回值写到吐血,最终还是得抄别人ACC++......

(留下不会写C++的泪水,顺便围观了大佬的数组映射实现)


这个数组映射就是mother[i]字符串是daughter[i]的母亲(父节点)。

没有什么特别的,只是不需要写结构体,虽然查找父节点没有结构体链表快不过这数据量是不会超时的。


我解释下两个函数是什么:

find:找父节点。找到了返回父节点(母亲)的名字,没有就返回 ""

issame:函数名不知道是什么意思。这个会找出abct级父节点,找不到就返回-1


输入后我们先以A牛开始,不停找A牛的祖先,直到这个祖先就是B牛的祖先为止。

假如搜索到老祖宗也没有找到B牛的祖先,说明AB不是亲属,输出"NOT RELATED"


记下AB牛到这个祖先的辈分。如果两个值都是1,说明是同一个母亲,输出"SIBLINGS"

如果两个值都大于1,说明只是同一个祖母(以上),关系是"COUSINS"


不是这两种情况就是祖先或者祖姨母,用复杂的输出规则输出。


(抄大佬的)代码如下:

 

技术图片
 1 #include <stdio.h>
 2 #include <string>
 3 #include <stdlib.h>
 4 #include <algorithm>
 5 #include <iostream>
 6 
 7 using namespace std;
 8 
 9 int N;
10 string cowA,cowB;
11 string mother[102],daughter[102];
12 string now;
13 
14 string find(string a)
15 {
16     for(int i=0;i<N;i++)
17     {
18         if(a==daughter[i])
19             return mother[i];
20     }
21     return "";
22 }
23 int issame(string a,string b)
24 {
25     int ct=0;
26     while(b!="")
27     {
28         if(a==b)return ct;
29         b=find(b);
30         ct++;
31     }
32     return -1;
33 }
34 int main()
35 {
36     cin >> N >> cowA >> cowB ;
37     for(int n=0;n<N;n++)
38         cin >> mother[n] >> daughter[n] ;
39     now=cowA;
40     int countA=0;
41     while(now!="")
42     {
43         if(issame(now,cowB)!=-1)break;
44         now=find(now);
45         countA++;
46     }
47     if(now=="")
48     {
49         puts("NOT RELATED");
50         return 0;
51     }
52     int countB=issame(now,cowB);
53     if(countA==countB && countA==1)
54     {
55         puts("SIBLINGS");
56         return 0;
57     }
58     else if(countA>1 && countB>1)
59     {
60         puts("COUSINS");
61         return 0;
62     }
63     else
64     {
65         if(countA<countB)
66         {
67             swap(cowA,cowB);
68             swap(countA,countB);
69         }
70         cout << cowB << " is the ";
71         for(int i=0;i<countA-2;i++)
72             printf("great-");
73         if(countA>1&&countB==0)
74             printf("grand-");
75         if(countB==0)
76             printf("mother");
77         else
78             printf("aunt");
79         cout << " of " << cowA << endl ;
80     }
81     return 0;
82 }
View Code

 

以上是关于[ 题解 ] [ 最小公共父节点 ] E. Family Tree的主要内容,如果未能解决你的问题,请参考以下文章

AIM Tech Round 3 (Div. 2) E. Centroids

[LeetCode] 1123. Lowest Common Ancestor of Deepest Leaves 最深叶结点的最小公共父节点

[ 题解 ] [ 二分+模拟 ] E. Convention

C++ 亲历面试题

luogu P2661 信息传递 题解

Codeforces Round #646 (Div. 2) E. Tree Shuffling(树上dp)