当前位置: 首页 > news >正文

树的直径 —— 即一棵树的最长路 附题(大臣的旅费 by蓝桥杯)

直接上求法:两遍bfs就可以求得最长路的两个端点。

参考结论:从任意一点出发能搜到的最远的点一定是最长路两个端点中的一个。

(注意:最远可以是权值最远,也可以是边数最多,总之思想是相通的,求法也一样)

证明如下:

首先,设a -- b 是最长路

① 设点u为最长路a -- b上的一个点,所以从该点出发,所能到达的最远的点肯定是a,b之一。

② 设点u不是最长路a -- b上的一点,这里还有一个小结论,就是u到所能到达的最远的点v肯定会与该树的最长路相交,在这先设一个点t为最长路a -- b上的一点且该点是u到最远点路径与a -- b最长路的交点,所以很容易想到了,再假如 a是u到达最远的点。

d[u -- v] = d[u -- t] + d[t -- a].

反证法证明:如果u到最远点v与a--b无交点,即 dis[u -- v] >d[u -- t] + d[t -- a].

d[u -- v] + d[u -- t] + d[t -- b] > d[u -- t] + d[t -- a] + d[t -- b] (== d[a -- b]); 此时与最长路是a -- b相矛盾,反证成功。


在下面附上往年的一道蓝桥杯题目——大臣的旅费


历届试题 大臣的旅费  
时间限制:1.0s   内存限制:256.0MB
       
问题描述

很久以前,T王国空前繁荣。为了更好地管理国家,王国修建了大量的快速路,用于连接首都和王国内的各大城市。

为节省经费,T国的大臣们经过思考,制定了一套优秀的修建方案,使得任何一个大城市都能从首都直接或者通过其他大城市间接到达。同时,如果不重复经过大城市,从首都到达每个大城市的方案都是唯一的。

J是T国重要大臣,他巡查于各大城市之间,体察民情。所以,从一个城市马不停蹄地到另一个城市成了J最常做的事情。他有一个钱袋,用于存放往来城市间的路费。

聪明的J发现,如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离有关,在走第x千米到第x+1千米这一千米中(x是整数),他花费的路费是x+10这么多。也就是说走1千米花费11,走2千米要花费23。

J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?

输入格式

输入的第一行包含一个整数n,表示包括首都在内的T王国的城市数

城市从1开始依次编号,1号城市为首都。

接下来n-1行,描述T国的高速路(T国的高速路一定是n-1条)

每行三个整数Pi, Qi, Di,表示城市Pi和城市Qi之间有一条高速路,长度为Di千米。

输出格式

输出一个整数,表示大臣J最多花费的路费是多少。

样例输入1
5
1 2 2
1 3 1
2 4 5
2 5 4
样例输出1
135
输出格式

大臣J从城市4到城市5要花费135的路费。

分析:很明显,题意告诉我们这是一棵树,由此可以想到是要求最长路。

下面贴代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
struct node{
	int u, v, w, next;
}e, edge[1000005];
int head[100005], book[100005];
int n, no;
void init(){
	no = 1;
	for(int i = 1; i <= n; ++i) {
		head[i] = -1;
		book[i] = 0;
	}
}
void add(int u, int v, int w){		//使用前向星来存储边的信息
	edge[no].u = u;
	edge[no].v = v;
	edge[no].w = w;
	edge[no].next = head[u];
	head[u] = no++;
}
int bfs(int x, long long &sum){
	int k, ans, max, va;
	max = 0;
	memset(book ,0, sizeof book);
	queue<node> q;
	e.v = x;
	e.w = 0;
	q.push(e);
	while(!q.empty()){				//通过队列不断更新,最大的距离,并记录当时的点
		e = q.front();
		q.pop();
		if(book[e.v]) continue;
		if(max < e.w){
			max = e.w;
			ans = e.v;
		}
		va = e.w;
		book[e.v] = 1;
		k = head[e.v];
		while(k != -1){
			if(book[edge[k].v] == 0){
				e.w = va+edge[k].w;	//用出队的权值+该点所能抵达的点的权值
				e.v = edge[k].v;
				e.u = edge[k].u;
				q.push(e);
			}
			k = edge[k].next;
		}
	}
	sum = max;
	return ans;
}
int main(){
	int i, u, v, w, a, b, ans;
	long long sum;
	cin >> n;
	init();
	for(i = 1; i < n; ++i){
		cin >> u >> v >> w;
		add(u, v, w);
		add(v, u, w);
	}
	if(n == 1) printf("0\n");
	else{
		sum = 0;
		a = bfs(1, sum);			//两次bfs获取最长路两端点,并用sum作为输出参数获得最长路的大小
		sum = 0;
		b = bfs(a, sum);
		printf("%lld\n", sum*10+sum*(sum+1)/2);
	}
	return 0;
}

继续加油~


相关文章:

  • 一个关于按位或的故事~~(QDU-码农必修)
  • ConcurrentHashMap 解读(一)
  • Today一只菜鸡的PAT甲级测试(PAT1124, PAT1125, PAT1126, PAT1127)
  • 快速排序--自行实现+qsort+sort
  • 归并排序--二路归并
  • quartz定时任务时间设置描
  • ctype.h头文件中的tolower和toupper以及cctype其他函数的应用
  • mbr损坏以及grub.conf的配置文件丢失或出错的方法
  • 单链表的基本操作
  • 抽象类与接口的区别
  • 不常用的模拟链表
  • Floyed-Warshall-求最短路
  • Server should be SSL-aware but has no certificate
  • Dijkstra求最短路(邻接表存储,前向星存储,堆优化)
  • linux虚拟机中和主机三种网络连接方式的区别
  • 《Java编程思想》读书笔记-对象导论
  • CEF与代理
  • Centos6.8 使用rpm安装mysql5.7
  • express如何解决request entity too large问题
  • HashMap剖析之内部结构
  • Invalidate和postInvalidate的区别
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • TCP拥塞控制
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 精彩代码 vue.js
  • 如何设计一个比特币钱包服务
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 阿里云重庆大学大数据训练营落地分享
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • #pragma pack(1)
  • $.proxy和$.extend
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (力扣)1314.矩阵区域和
  • (四) 虚拟摄像头vivi体验
  • (图)IntelliTrace Tools 跟踪云端程序
  • (转)微软牛津计划介绍——屌爆了的自然数据处理解决方案(人脸/语音识别,计算机视觉与语言理解)...
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET Framework .NET Core与 .NET 的区别
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • .net操作Excel出错解决
  • .NET企业级应用架构设计系列之应用服务器
  • .xml 下拉列表_RecyclerView嵌套recyclerview实现二级下拉列表,包含自定义IOS对话框...
  • :如何用SQL脚本保存存储过程返回的结果集
  • [ActionScript][AS3]小小笔记
  • [C#]OpenCvSharp使用帧差法或者三帧差法检测移动物体
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • [CC2642r1] ble5 stacks 蓝牙协议栈 介绍和理解
  • [C语言][C++][时间复杂度详解分析]二分查找——杨氏矩阵查找数字详解!!!
  • [ERROR] 不再支持目标选项 5。请使用 7 或更高版本
  • [HarmonyOS]第一课:从简单的页面开始