codeforces E. Family Tree(LCA)

E. Family Tree

time limit per test:1 second
memory limit per test:256 megabytes
input:standard input
output:standard output

Farmer John owns a family-run farm that has been passed down over several generations, with a herd of cows whose familial roots can similarly be traced back several generations on the same farm. By examining old records, Farmer John is curious how the cows in his current herd are related to each-other. Please help him in this endeavor!

Input

The first line of input contains N (1≤N≤100) followed by the names of two cows. Cow names are each strings of at most 10 uppercase letters (A…Z). Farmer John is curious about the relationship between the two cows on this line of input.

The next N lines each contain two cow names X and Y, indicating that X is the mother of Y.

Output

You should print one line of output indicating the relationship between the two cows specified on the first line of input (for simplicity, let’s call these two cows BESSIE and ELSIE for the examples below). Here are the different types of relationships that are possible:

You should output “SIBLINGS” if BESSIE and ELSIE have the same mother.
BESSIE might be a direct descendant of ELSIE, meaning that ELSIE is either the mother, grand-mother, great-grand-mother, great-great-grand-mother, etc., of BESSIE. If this is the case, you should print “ELSIE is the (relation) of BESSIE”, where (relation) is the appropriate relationship, for example “great-great-grand-mother”.
If ELSIE is a child of an ancestor of BESSIE (and ELSIE is not herself an ancestor or sister of BESSIE), then ELSIE is BESSIE’s aunt. You should output “ELSIE is the aunt of BESSIE” if ELSIE is a child of BESSIE’s grand-mother, “ELSIE is the great-aunt of BESSIE” if ELSIE is a child of BESSIE’s great-grand-mother, “ELSIE is the great-great-aunt of BESSIE” if ELSIE is a child of BESSIE’s great-great-grand-mother, and so on.
If BESSIE and ELSIE are related by any other means (i.e., if they share a common ancestor), they are cousins, and you should simply output “COUSINS”.
You should output “NOT RELATED” if BESSIE and ELSIE have no common ancestor, or neither is directly descended from the other.
The following diagram helps illustrate the relationships above, which are the only relationship types you need to consider.

Observe that some relationships like “niece” (daughter of sister) are not necessary since if BESSIE is the niece of ELSIE, then ELSIE is BESSIE’s aunt.

在这里插入图片描述

Example

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

分析

给出A和B及各家族成员的母子关系,问A和B什么亲戚关系;
就是一个最小公共祖先查找。只不过要记录到公共祖先的长度。根据长度关系来输出亲辈关系。而且也有可能没有公共祖先;
具体的关系在图上已经很清楚了,只需要把连线的权值设为1,做起来就比较容易了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<algorithm>
#define MS(X) memset(X,0,sizeof(X))
#define MSC(X) memset(X,-1,sizeof(X))
typedef long long LL;
using namespace std;
const int maxn=1e3;
string a,b,save[maxn],dug[maxn];
int n,i;
string mama(string a){
    for(int i=1;i<=n;i++) if(a==dug[i]) return save[i];
    return "";
}
int chk(string a,string b){
    int dis=0;
    while(b!=""){
        if(a==b) return dis;
        b=mama(b);
        dis++;
    }
    return -1;
}
int main(){
    int da=0,db=0;
    cin>>n>>a>>b;
    string sa=a;
    for(i=1;i<=n;i++){
        cin>>save[i]>>dug[i];
    }
    while(sa!=""){
        if(chk(sa,b)!=-1) break;
        sa=mama(sa);
        da++;
    }
    if(sa==""){
        printf("NOT RELATED\n");
        return 0;
    }
    db=chk(sa,b);
    if(da>1&&db>1) printf("COUSINS\n");
    else if(da==1&&db==1) printf("SIBLINGS\n");
    else{
        if(da>db){
            string t=a;a=b,b=t;
            int dt=da;da=db,db=dt;
        }
        cout<<a<<" is the ";
        int ht=db-da;
        for(;ht>=3;ht--) printf("great-");
        if(a==sa){
            if(ht==2) printf("grand-");
            printf("mother");
        }
        else{
            if(ht==2) printf("great-");
            printf("aunt");
        }
        cout<<" of "<<b<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值