hihocoder周赛(树的最长距离)

本文探讨了一个关于道路建设的问题:在一个由n个城市组成的国家里,如何通过若干阶段的施工,使得任意两个城市间都能直接通过无向道路相连。文章提供了一种算法实现方案,包括数据结构的设计与递归算法的应用,并最终给出了计算最少施工阶段数的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目4 : 道路建设

时间限制:20000ms

单点时限:1000ms

内存限制:256MB

描述

H 国有 n 座城市和 n-1 条无向道路,保证每两座城市都可以通过道路互相到达。现在 H 国要开始施工,施工分若干个阶段,第 i 个阶段会建设无向道路 (x,y) ,当且仅当存在一个数 z,满足 x ≠ z, x ≠ y, z ≠ y,且在第 i-1 个阶段后,存在无向道路 (x,z), (z,y).

现在 H 国的国王想知道,在几个阶段后,每两个不同的城市之间都有一条无向道路.

输入

第一行一个正整数 n

接下来 n-1 行,每行两个正整数 (x,y),描述一开始的一条无向道路 (x,y)

1 ≤ n ≤ 105

输出

输出最少几个阶段后,每两个不同的城市之间都有一条无向道路.



#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+5;
vector<int>g[N];
int first[N], second[N];//first 存储到达最远结点的长度,second记录次长度
int res = 0;
void dp(int u, int pre) {
int k = g[u].size();
for(int i = 0; i < k; i++) {
if(g[u][i]==pre)continue;///子结点 == 父结点编号 边重复不需要重复扫
dp(g[u][i],u);
/**当子结点的最长边+1 (加上到父结点的距离1)大于父结点的最长边 更新父结点的最长边和次长边**/
if(first[g[u][i]]+1>=first[u])second[u]=first[u],first[u]=first[g[u][i]]+1;
else if(first[g[u][i]]+1>second[u])second[u]=first[g[u][i]]+1;
}
/**在以当前结点为根节点的子树中,最远两个结点的距离为first+second**/
res = max(res, first[u]+second[u]);
return ; 
}
int main() {
// freopen("data.in","r",stdin);
int n,u,v;
scanf("%d",&n);
for(int i=1; i<n; i++) {
scanf("%d %d",&u,&v);
g[u].push_back(v);
g[v].push_back(u);
}
dp(1,0);
long long ans = ceil(log2(res*1.0));
cout<<ans<<endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值