思路:用结构体记录下每个节点的父节点。从叶子节点依次往上遍历,直到与后面的节点最近的父节点停止,再从该节点向下遍历至后面的叶子节点,将结果存进ans数组,并统计每个数出现的次数,大于2时结束操作,输出-1,否则输出ans数组。
#include <cstdio>
#include <cstring>
const int LEN=330;
struct Node
{
int fa;
int n;
int ncount;
}node[LEN];
int k;
int last[LEN]; //依次保存叶子节点
int order[LEN][LEN]; //每个叶子节点向上遍历至根节点的路径,用哈希的方式储存
int cou[LEN]; //用于统计每个节点被遍历的次数
int ans[LEN*LEN];
int res;
int f;
void ini() //初始化函数
{
memset(node,0,sizeof(node));
memset(order,0,sizeof(order));
memset(cou,0,sizeof(cou));
res=0;
f=1;
for(int i=1;i<=k;i++)
node[i].n=i;
order[0][1]=1;
node[1].fa=0;
}
void traversal(int t) //从下往上依次沿父节点遍历,并用哈希方式存入数组。
{
int a=t;
int root=0;
while(t!=root)
{
order[a][t]=1;
t=node[t].fa;
}
}
int find(int a,int b) //找出两个节点最近的父节点
{
int m=a>b?a:b;
for(int i=m;i>=1;i--)
{
if(order[a][i] && order[b][i])
{
return i;
}
}
}
void add(int a,int b) //按遍历顺序读入ans数组
{
int tmp=find(a,b);
for(int i=a;i>=tmp;i--)
{
if(order[a][i])
{
ans[res++]=i;
cou[i]++;
if(cou[i]>2)
{
f=0;
return;
}
}
}
for(int i=tmp;i<=b;i++)
{
if(order[b][i])
{
ans[res++]=i;
cou[i]++;
if(cou[i]>2)
{
f=0;
return;
}
}
}
}
void addlast(int t) //最后返回根节点经过的路径
{
int root=0;
t=node[t].fa;
while(t!=root)
{
ans[res++]=t;
cou[t]++;
t=node[t].fa;
if(cou[t]>2)
{
f=0;
return;
}
}
}
int main()
{
while(scanf("%d",&k)!=EOF)
{
ini();
for(int i=1;i<k;i++)
{
int a,b;
scanf("%d %d",&a,&b);
node[b].fa=a;
node[a].ncount++; //用于判断最后一行有几个叶子节点,(是0的时候说明是叶节点)
}
int m=0;
for(int i=1;i<=k;i++)
if(node[i].ncount==0)
m++;
for(int i=1;i<=m;i++)
{
scanf("%d",&last[i]);
traversal((last[i]));
}
last[0]=1;
for(int i=0;i<m;i++)
{
add(last[i],last[i+1]);
if(f==0)
{
printf("-1\n");
return 0;
}
}
addlast(last[m]);
if(f==0)
{
printf("-1\n");
return 0;
}
for(int i=0;i<res;i++)
{
printf("%d",ans[i]);
if(i!=res-1)
printf(" ");
}
printf("\n");
}
return 0;
}