一道非常清晰的搜索题
先上AC码
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=108;
struct node{
int w,l,r;
//w=到父节点距离
//l=左子节点编号
//r=右子节点编号
}no[N];
int ans=-1;//最长路径长度
void dfs(int ls,int rs,int sum,int cur)
{
sum+=no[cur].w;
ans=max(sum,ans);
if(ls) dfs(no[ls].l,no[ls].r,sum,ls);
if(rs) dfs(no[rs].l,no[rs].r,sum,rs);
}
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>no[i].w>>no[i].l>>no[i].r;
}
dfs(no[1].l,no[1].r,0,1);
cout<<ans<<endl;
return 0;
}
现在知道的有:
①这个二叉树每个节点的编号
②每个节点到其父节点的距离
(可看成权,根节点的权是0)
③每个节点的两个子节点的编号
(如果都是0就代表它是叶节点)
这样就允许我们找到这个二叉树的每一根枝,也就是遍历每一条可能走的路径
不过首先,按照要求,先输入
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>no[i].w>>no[i].l>>no[i].r;
}
下面看DFS函数部分,实际上它本身很短
void dfs(int ls,int rs,int sum,int cur)
{
sum+=no[cur].w;
ans=max(sum,ans);
if(ls) dfs(no[ls].l,no[ls].r,sum,ls);
if(rs) dfs(no[rs].l,no[rs].r,sum,rs);
}
这里的具体思路是
从根开始往下找,每次先找左子节点,然后把它的权(距离)加到路径总长度里,也就是:
sum+=no[cur].w;
走到头了之后就停止,然后嵌套的DFS函数逐层结束,结束到有右子节点的节点为止,然后进入这个右子节点,在以之为根的子树里继续按照上述思路进行遍历,写出来就两行:
if(ls) dfs(no[ls].l,no[ls].r,sum,ls);
if(rs) dfs(no[rs].l,no[rs].r,sum,rs);
这样下来就可以走遍所有可能的路了
但是光走遍所有的路是不够的,我们需要求的是最长路径的长度
所以定义了一个ans,用来对每次路径的长度sum取最大值:
ans=max(sum,ans);
最后,主函数里需要做的就只是利用DFS函数进行搜索然后输出了
dfs(no[1].l,no[1].r,0,1);
cout<<ans<<endl;
return 0;