首页 > 代码库 > 家谱(gen)

家谱(gen)

题目描述

输入文件名  GEN.IN 

输出文件名    GEN.OUT

时间限制      2S

 

现代的人对于本家族血统越来越感兴趣,现在给出充足的父子关系,请你编写程序找到某个人的最早的祖先。

 

输入

输入文件由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系由二行组成,用#name的形式描写一组父子关系中的父亲的名字,用+name的形式描写一组父子关系中的儿子的名字;接下来用?name的形式表示要求该人的最早的祖先;最后用单独的一个$表示文件结束。规定每个人的名字都有且只有6个字符,而且首字母大写,且没有任意两个人的名字相同。最多可能有1000组父子关系,总人数最多可能达到50000人,家谱中的记载不超过30代。

 

输出

按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式:本人的名字+一个空格+祖先的名字+回车。

 

样例

GEN.IN

#George

+Rodney

#Arthur

+Gareth

+Walter

#Gareth

+Edward

?Edward

?Walter

?Rodney

?Arthur

$

 

GEN.OUT

Edward Arthur

Walter Arthur

Rodney George

Arthur Arthur

分析

一边输入一遍输出

输入主要是判断第一个字符是# +还是?

因为这个关系到输出

用 do while循环输入就可以

结构体四个参数 num父结点编号 numself自己的编号 s父结点的名字 sself自己的名字

输入的时候 默认为父结点为自己 输入的时候还要挨个判断里面是否已经放过了

这就要for循环 (会超时~)

可以路径压缩

错误1:b=m s2=s1位置放错 把 if(father[m].num==0)和 if(ch==‘#‘)放到一起

   应该只要是输入#号 就存一下m 和 s1

   如果把条件合并 那么已经放过父结点的结点即使再是父结点也无法更新

错误2:如果已经做过父结点 就不会再做子结点

   在if(ch==‘+‘)里面修改 判断一下

   既然能判断 就一定输入加号 再判断它的父结点是否和本身相等

   或者压根没放过父结点 就存下来m 和 s1

代码

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
struct ff{
    int numself;
    int num;
    string s;
    string sself;
};
ff father[50005];
int find(int);
int main()
{
//    freopen("GEN.IN","r",stdin);
//    freopen("GEN.OUT","w",stdout);
    int m=0,b,n=0;
    char ch;
    string s1,s2;
    do
    {
    m=n;
    m++;
    n++;
    cin>>ch>>s1;
    for(int i=1;i<=m;i++)
        if(father[i].sself==s1)
        {
            n=m;
            m=i;
            break;
        }
    if(ch==#)
        {
            if(father[m].num==0)
            {
            father[m].numself=m;
            father[m].sself=s1;
            father[m].num=m;
            father[m].s=s1;
            }
        b=m;
        s2=s1;
        }
    if(ch==+)
        {
            father[m].numself=m;
            father[m].sself=s1;
            if(father[m].s==father[m].sself||father[m].num==0)
            {
            father[m].num=b;
            father[m].s=s2;
            }
        }
    if(ch==?)
    {
        for(int i=1;i<=m;i++)
            if(father[i].sself==s1)
                {
                cout<<s1<<" "<<father[find(father[i].numself)].s<<endl;
                break;
                }
    }
    }
    while(ch!=$);
    return 0;
}
int find(int x)
{
    if(father[x].num!=x)
        father[x].num=find(father[x].num);
    return father[x].num;
}

 

家谱(gen)