侧边栏壁纸
  • 累计撰写 192 篇文章
  • 累计创建 2 个标签
  • 累计收到 87 条评论

【题解】树的直径

Allen Best
2022-10-13 / 0 评论 / 0 点赞 / 21 阅读 / 1,275 字
温馨提示:
本文最后更新于 2023-04-25,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目描述
给定一棵拥有 n 个结点的树,1 号点为根,请找出这棵树的直径。所谓直径就是树上最远的两点的距离。

输入格式
第一行:单个整数表示 n;
第二行:n−1 个整数表示 p_2到 p_n,p_i表示 i 号点父亲的编号,保证有 1≤pi<i。

输出格式
单个整数:表示树的直径。

数据范围
对于 30%30% 的数据,n≤20;
对于 60%60% 的数据, n≤5000;
对于 100%100% 的数据, 1≤n≤200,000。
样例数据
输入:
4
1 1 1
输出:
2
输入:
4
1 2 3
输出:
3
【题解】
暴力:
使用一次bfs 或者 dfs 求出所有点和v 的距离,然后再用n次搜索,找到所有点的距离。(部分数据超时)
使用结论
任选一个点v,找距离v最远的一个点u,再找一个点u最远的点w,则u-w 是最远距离。
可以使用搜索完成题目。(广搜,若用深搜,当点是一路悬挂下来的话,栈空间开销过大)

#include<bits/stdc++.h>
#include <iostream>     // cin  cout的头文件  基本输入流
#include <iomanip>   //cout输出时,保留小数fixed、setprecision的头文件 参数化输入/输出
#include <cstdio>    //scanf、printf的头文件  定义输入/输出函数
#include <cmath>     //sqrt()求平方根、定义数学函数
#include <algorithm>    //STL通用算法
#include <cstring>
#include <string>
using namespace std;
const int N=2e5+10;
vector<int> e[N];//e[i]存储 与i相邻的节点 
int last,dis;//记录 哪个距离s最远,最远距离是多少
bool vis[N];//是否访问过 
struct node{
	int f;//当前点 
	int l;//距离 
};
queue<node>q;
void bfs(int s){
	memset(vis,0,sizeof(vis));
	vis[s]=1;
	node n_p;
	n_p.f=s;
	n_p.l=0; 
	q.push(n_p);
	while(!q.empty()){
		node p=q.front();
		q.pop();
		last=p.f;
		dis=p.l;
		for(int i=0;i<e[p.f].size();i++){
			int x=e[p.f][i];
			if(vis[x])
			continue;
			node nxp;
			nxp.f=x;
			nxp.l=p.l+1;
			q.push(nxp);
			vis[x]=1;
		}
	}
} 
int main(){
	int n;
	cin>>n;
	for(int i=2;i<=n;i++){
		int f;
		cin>>f;
		e[f].push_back(i);
		e[i].push_back(f);
	}
	//
	bfs(1);
	bfs(last);
	cout<<dis;
	return 0;
}

0

评论区