题目背景
现代的人对于本家族血统越来越感兴趣。
题目描述
给出充足的父子关系,请你编写程序找到某个人的最早的祖先。
输入输出格式
输入格式:
输入由多行组成,首先是一系列有关父子关系的描述,其中每一组父子关系中父亲只有一行,儿子可能有若干行,用#name的形式描写一组父子关系中的父亲的名字,用+name的形式描写一组父子关系中的儿子的名字;接下来用?name的形式表示要求该人的最早的祖先;最后用单独的一个$表示文件结束。
输出格式:
按照输入文件的要求顺序,求出每一个要找祖先的人的祖先,格式:本人的名字+一个空格+祖先的名字+回车。
输入输出样例
输入样例#1:
#George
+Rodney
#Arthur
+Gareth
+Walter
#Gareth
+Edward
?Edward
?Walter
?Rodney
?Arthur
$
输出样例#1:
Edward Arthur
Walter Arthur
Rodney George
Arthur Arthur
说明
规定每个人的名字都有且只有6个字符,而且首字母大写,且没有任意两个人的名字相同。最多可能有1000组父子关系,总人数最多可能达到50000人,家谱中的记载不超过30代。
用strcpy(s1,s2+1)可以把字串s2的第二位到最后一位截取出来。加个map,直接用并查集做就行。
然而借这个水题发现了细节问题:map的使用还是不熟。没有做好从id到字串的反映射,导致最后输出答案错误。
1 /*by SilverN*/ 2 //WA 1:map反映射错误 3 #include<algorithm> 4 #include<iostream> 5 #include<cstring> 6 #include<cstdio> 7 #include<cmath> 8 #include<map> 9 using namespace std; 10 const int mxn=80010; 11 int n; 12 char ss[10]; 13 char s[mxn][10]; 14 map<string,int>mp; 15 int id=0; 16 // 17 int fa[mxn]; 18 int find(int x){ 19 if(fa[x]==x)return x; 20 return fa[x]=find(fa[x]); 21 } 22 // 23 int main(){ 24 char ch[10]; 25 n=0; 26 for(int i=1;i<=80000;i++)fa[i]=i; 27 int last=0; 28 while(scanf("%s",ch)!=EOF){ 29 if(ch[0]=='$')break; 30 n++; 31 strcpy(ss,ch+1); 32 if(!mp[ss]){ 33 mp[ss]=++id; 34 strcpy(s[id],ss); 35 } 36 // printf("%s ",s[n]); 37 int idn=mp[ss]; 38 if(ch[0]=='#'){ 39 last=idn; 40 continue; 41 } 42 else if(ch[0]=='+'){ 43 fa[idn]=last; 44 continue; 45 } 46 else if(ch[0]=='?'){ 47 idn=find(idn); 48 printf("%s %s ",ss,s[idn]); 49 } 50 } 51 return 0; 52 }