树的中心
2023/5/23 18:22:14
本文主要是介绍树的中心,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目描述
给定一棵树,树中包含 n 个结点(编号1~n)和 n−1条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。
输入格式
第一行包含整数 n。
接下来 n−1行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi之间存在一条权值为 ci 的边。
输出格式
输出一个整数,表示所求点到树中其他结点的最远距离。
数据范围
1≤n≤10000,
1≤ai,bi≤n,
1≤ci≤10^5
输入样例
5 2 1 1 3 2 1 4 3 1 5 1 1
输出样例
2
题目分析
代码实现
#include<iostream> #include<cstring> #include<algorithm> using namespace std; #define int long long const int N=1e4+5,M=2*N,INF=0x3f3f3f3f; int h[N],e[M],ne[M],w[M],idx; int leaf[N],d1[N],d2[N],up[N],next1[N]; void add(int x,int y,int z){ e[idx]=y,w[idx]=z,ne[idx]=h[x],h[x]=idx++; } int dfs_down(int u,int f){ int dist=0; d1[u]=d2[u]=0; for(int i=h[u];~i;i=ne[i]){ int j=e[i]; //防止回头 if(j==f)continue; //求当前结点向下的路径 int dis=dfs_down(j,u)+w[i]; //更新该结点向下的最长路径 dist=max(dist,dis); //更新最长路径和次长路径 if(dis>d1[u])d2[u]=d1[u],d1[u]=dis,next1[u]=j; else if(dis>d2[u])d2[u]=dis; } //如果该结点向下没有边,则说明该结点为叶子结点 if(dist==0)leaf[u]=1; return dist; } void dfs_up(int u,int f){ for(int i=h[u];~i;i=ne[i]){ int j=e[i]; if(j==f)continue; //如果u结点向下的最长路径经过了j, //则表示j结点向上的最长路径为u的次长路径和u结点向上的最长路径的最大值加上w[i] if(next1[u]==j)up[j]=max(up[u],d2[u])+w[i]; //否则则表示j结点向上的最长路径为u的最长路径和u结点向上的最长路径的最大值加上w[i] else up[j]=max(up[u],d1[u])+w[i]; dfs_up(j,u); } } signed main(){ int n,x,y,z; cin>>n; memset(h,-1,sizeof h); for(int i=0;i<n-1;i++){ cin>>x>>y>>z; //建立无向边 add(x,y,z); add(y,x,z); } //更新向下的最长路径和次长路径长度 dfs_down(1,-1); //更新向上的最长路径 dfs_up(1,-1); int res=INF; for(int i=1;i<=n;i++){ //如果该结点是叶子结点,则只需要比较向上的最长路径即可 if(leaf[i])res=min(res,up[i]); //否则需要比较向上的最长路径和向下的最长路径 else res=min(res,max(up[i],d1[i])); } cout<<res<<endl; return 0; }
这篇关于树的中心的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-15Springboot应用的多环境打包学习
- 2024-10-15Springboot应用的生产发布学习
- 2024-10-15创建Springboot项目学习:新手入门教程
- 2024-10-15创建springboot项目学习:新手入门教程
- 2024-10-14Java创业学习:新手入门教程
- 2024-10-14JAVA创业学习:新手入门教程
- 2024-10-14Java创业学习:从零开始的Java编程教程
- 2024-10-14Java对接阿里云智能语音服务学习
- 2024-10-14JAVA对接阿里云智能语音服务学习教程
- 2024-10-14Java副业学习:从入门到实战的简单教程