当前位置: 首页> 财经> 金融 > 树的直径两种求解方式(dfs,dp)

树的直径两种求解方式(dfs,dp)

时间:2025/8/26 17:20:29来源:https://blog.csdn.net/m0_70897036/article/details/139974385 浏览次数:0次

1.dfs

void dfs(int now,int fa,int weight)//now:起点,fa:now的父节点,weight:搜索到当前点的路径长度
{if(l<weight)//发现更大的长度,更新id与l{id=now;l=weight;}for(auto nxt:e[now])//对于每一个子节点{int v=nxt.v,w=nxt.w;if(v==fa)continue;dfs(v,now,weight+w);}return ;
}

先以任一点为起点进行一次搜索,搜索结束后的id为下一次搜索的起点,第二次搜索完成后,所得到的id与第一次的id之间的路径就是树的直径,长度为l。
两次dfs的优点是:可以记录直径的起点,再配合一个dfs可以求出直径上的每一个点。
求得路径上的每一个点:

void dfs(int now,int fa,int ed)//now为第一次得到的id,ed为第二次得到的id
{for(auto nxt:e[now]){int v=nxt.v;if(flag==1)return ;//如果已经找到了到达ed的路径,直接退出if(v==fa)continue;if(v==ed){flag=1;//找到终点,更新flag,告诉后面的直接退出。road[now]=ed;//路径记录return ;}road[now]=v;//路径记录dfs(v,now,ed);}return ;
}

缺点:无法解决负边权的情况。

dp

int dfs(int now,int fa)
{int d1=0,d2=0;//d1记录以now开始的最大长度,d2记录now开始的次大长度for(auto nxt:e[now]){int v=nxt.v,w=nxt.w;if(fa==v)continue;int d=dfs2(v,now)+w;//d为从以v为根节点的子树可以获得的最大长度if(d>d1){d2=d1,d1=d;}//根据d与d1,d2的大小关系进行更新else if(d>d2){d2=d;}l=max(l,d1+d2);//l记录整个树里面的最大直径}return d1;//返回最大以now为根节点的最大长度
}

优点:可以处理负边权的树。
缺点:只能求一个树的直径的长度,其他的求不出(起点,终点,路径)。

关键字:树的直径两种求解方式(dfs,dp)

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: