找家谱成员
输入若干行,每一行的第一个输入为家谱中的某成员,该行接着输入的信息为每个孩子姓名。
最后一行的输入为要求查找的二个家谱成员的关系。
要求,根据输入的家谱成员信息,建立二叉树家谱关系图,并输入二位待查成员在家谱中的关系,包括输出他们最近邻的共同祖先以及在家谱中相差的层次数。
输入:
Ye Shu Ba
Shu Ge Mei1
Ba Self Mei2
Ge Son1 Son2
Son2 Mei1
输出:
Shu 1
思路:因为名字都是唯一的,所以用名字生成id,方便查找;把树存储为无向图;
#include
using namespace std;
int iname=-1;
vector names;
vector splitc(char s[],char ll[])//把字符串按ll分割;
{
vector rs;
const char *sp=ll;
char *p;
p=strtok(s,sp);
while(p)
{
rs.push_back(p);
p=strtok(NULL,sp);
}
return rs;
}
int searchByName(string b)//根据字符获取id
{
for(int i=0; i p1,p2;
vector p[1000];
int path[10000]= {0};
bool visit[1000]= {false};
void printPath(int d,int t)
{
if(t==1)
{
if(path[d]>=0)
{
p1.push_back(names[path[d]]);
printPath(path[d],t);
}
}
else
{
if(path[d]>=0)
{
p2.push_back(names[path[d]]);
printPath(path[d],t);
}
}
}
void dfs(int s,int d,int t)
{
// printf("%s入队列\n",names[s].c_str());
visit[s]=true;
if(s==d)
{
printPath(d,t);
return;
}
for(int i:p[s])
{
if(!visit[i])
{
path[i]=s;
dfs(i,d,t);
}
}
// printf("%s出队列\n",names[s].c_str());
}
void bt(int a,int b)
{
//从根节点开始查找;
dfs(0,a,1);
//memset(path,10000,sizeof(path));
fill(path,path+10000,-1);
memset(visit,false,sizeof(visit));
dfs(0,b,2);
int cnt=p2.size()-p1.size();
string rs="";
for(string s:p2)
{
for(string s2:p1)
{
if(s==s2&&rs==""){
rs=s;
break;
}
}
}
printf("%s %d",rs.c_str(),abs(cnt));
}
int main()
{
int a,b,dis;
char s[1000];
fill(path,path+10000,-1);
string re;
while(cin.getline(s,1000))
{
vector sss=splitc(s," ");//把字符串按空格分割;
int len=sss.size();
if(len==3)
{
int f=getId(sss[0]);
int l=getId(sss[1]);
int r=getId(sss[2]);
p[f].push_back(l);
p[l].push_back(f);
p[f].push_back(r);
p[r].push_back(f);
}
else if(len==2)
{
int a=getId(sss[0]);
int b=getId(sss[1]);
bt(a,b);
break;
}
}
// printf("%s %d",re.c_str(),dis);
return 0;
}