P4408 逃学的小孩 题解
题目描述

Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚,他们决定在尽量短的时间内找到Chris。他们告诉Chris的老师:“根据以往的经验,Chris现在必然躲在朋友Shermie或Yashiro家里偷玩《拳皇》游戏。现在,我们就从家出发去找Chris,一但找到,我们立刻给您打电话。”说完砰的一声把电话挂了。
Chris居住的城市由N个居住点和若干条连接居住点的双向街道组成,经过街道x需花费Tx分钟。可以保证,任两个居住点间有且仅有一条通路。Chris家在点C,Shermie和Yashiro分别住在点A和点B。Chris的老师和Chris的父母都有城市地图,但Chris的父母知道点A、B、C的具体位置而Chris的老师不知。
为了尽快找到Chris,Chris的父母会遵守以下两条规则:
如果A距离C比B距离C近,那么Chris的父母先去Shermie家寻找Chris,如果找不到,Chris的父母再去Yashiro家;反之亦然。
Chris的父母总沿着两点间唯一的通路行走。
显然,Chris的老师知道Chris的父母在寻找Chris的过程中会遵守以上两条规则,但由于他并不知道A,B,C的具体位置,所以现在他希望你告诉他,最坏情况下Chris的父母要耗费多长时间才能找到Chris?
输入格式
输入文件第一行是两个整数\(N(3 ≤ N ≤ 200000)\)和\(M\),分别表示居住点总数和街道总数。
以下M行,每行给出一条街道的信息。第\(i+1\)行包含整数\(U_i、V_i、T_i(1≤U_i, V_i ≤ N,1 ≤ T_i ≤ 1000000000)\),表示街道i连接居住点\(U_i\)和\(V_i\),并且经过街道i需花费\(T_i\)分钟。街道信息不会重复给出。
输出格式
输出文件仅包含整数T,即最坏情况下Chris的父母需要花费T分钟才能找到Chris。
输入样例
4 3
1 2 1
2 3 1
3 4 1
输出样例
4
题解
好久没见过思路这么简单的题了,但该WA还是要WA
首先这个图是一棵树
然后就很明确了,显然是树的直径,情况最差的时候,A点和B点之间的路径就是树的直径,然后C点就是使\(min(distance_{C,A},distance_{C,B})\)最大的C点.
首先DFS求出树的直径,然后遍历每一个点作为C点求出\(distance_{C,A},distance_{C,B}\),然后根据刚才的式子推出来即可.
有几个需要注意的点:
9 8
1 8 1000000000
8 7 1000000000
7 5 1000000000
1 3 1000000000
7 2 1000000000
1 6 1000000000
3 4 1000000000
8 9 1000000000
对于这个输入,应该输出8000000000,如果你输出的是负数说明你没有开long long.
直接些会TLE,在求距离的函数那里加一个记忆化即可
怎么感觉我写不是正解,代码也太丑了
再附赠一个数据:
输入:
4 3
1 2 1
1 3 1
1 4 2
输出:
5
代码
#include <cstdio>
#include <iostream>
#include <map>
#include <utility>
#define P pair<int, int>
using namespace std;
const int maxn = 200005;
int head[maxn], tot, maxi, n, m, ix, iy, iv;
long long maxv;
struct Edge {
int to, next;
long long value;
} edges[maxn << 1];
void add(int x, int y, long long value) {
edges[++tot].to = y;
edges[tot].next = head[x];
edges[tot].value = value;
head[x] = tot;
}
void dfs(int root, int fa, long long dis) {
if (dis > maxv) maxv = dis, maxi = root;
for (int x = head[root]; x; x = edges[x].next)
if (edges[x].to != fa) dfs(edges[x].to, root, dis + edges[x].value);
}
map<P, long long> save;
long long getd(int root, int fa, int target) {
if (root == target) return 0;
if(save.count(make_pair(root, target)))return save[make_pair(root, target)];
for (int x = head[root]; x; x = edges[x].next) {
if (edges[x].to == fa) continue;
long long r = getd(edges[x].to, root, target);
if (r != -1) {
save[make_pair(edges[x].to, target)] = r;
return r + edges[x].value;
}
}
return -1;
}
int main() {
scanf("%d%d", &n, &m);
while (m--) {
scanf("%d%d%d", &ix, &iy, &iv);
add(ix, iy, iv);
add(iy, ix, iv);
}
dfs(1, 0, 0);
int d1 = maxi;
maxv = 0, maxi = 0;
dfs(d1, 0, 0);
int d2 = maxi;
long long cmaxv = 0;
int cmaxi = 0;
for (int i = 1; i <= n; i++)
if (i != d1 && i != d2)
cmaxv = max(cmaxv, min(getd(i, 0, d1), getd(i, 0, d2)));
printf("%lld\n", cmaxv + maxv);
return 0;
}
P4408 逃学的小孩 题解的更多相关文章
- 洛谷 P4408 逃学的小孩 解题报告
P4408 [NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?&q ...
- 洛谷 P4408 [NOI2003] 逃学的小孩 题解
Analysis 题意虽然说先去谁家再去谁家,但是我们不需要管这个,因为AA.BB.CC三个点我们可以任意互相交换它们所代表的对象,所以题目要求的就是在一棵树上找到3个点AA.BB.CC令AB+BCA ...
- BZOJ1509 & 洛谷4408:[NOI2003]逃学的小孩——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1509 https://www.luogu.org/problemnew/show/P4408 sb ...
- 洛谷P4408 逃学的小孩
题目 求树的直径,因为任意两个居住点之间有且只有一条通路,所以这是一棵树. 根据题意父母先从C去A,再去B,或者反过来. 我们一定是要让A到B最大,也要让C到A和B的最小值最大. AB最大一定就是直径 ...
- [NOI2003]逃学的小孩 题解
前言 >原题传送门(洛谷)< 看了一下洛谷题面,这道NOI的题竟然是蓝的(恶评?),做了一下好像确实是蓝的... 解法 思路非常简单,找道树的直径,然后答案是直径长度加上最大的min(di ...
- 【BZOJ1509】[NOI2003]逃学的小孩 直径
[BZOJ1509][NOI2003]逃学的小孩 Description Input 第一行是两个整数N(3 N 200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的 ...
- BZOJ 1509[NOI 2003]逃学的小孩 树形dp
1509: [NOI2003]逃学的小孩 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 995 Solved: 505[Submit][Status][ ...
- [NOI2003]逃学的小孩(树的直径)
[NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听 ...
- BZOJ 1509: [NOI2003]逃学的小孩( 树形dp )
树形dp求出某个点的最长3条链a,b,c(a>=b>=c), 然后以这个点为交点的最优解一定是a+2b+c.好像还有一种做法是求出树的直径然后乱搞... ----------------- ...
随机推荐
- 汇编指令:push、pop
8086CPU出栈入栈都是以字为单位进行的. push ax 由一下两步完成 1.SP=SP-2 2.将ax中的内容送入SS:SP指向的内存单元 pop ax 1.将SS:SP指向的内存单元中的内容送 ...
- 调优 | Apache Hudi应用调优指南
通过Spark作业将数据写入Hudi时,Spark应用的调优技巧也适用于此.如果要提高性能或可靠性,请牢记以下几点. 输入并行性:Hudi对输入进行分区默认并发度为1500,以确保每个Spark分区都 ...
- 【asp.net core 系列】6 实战之 一个项目的完整结构
0. 前言 在<asp.net core 系列>之前的几篇文章中,我们简单了解了路由.控制器以及视图的关系以及静态资源的引入,让我们对于asp.net core mvc项目有了基本的认识. ...
- 6.keras-基于CNN网络的Mnist数据集分类
keras-基于CNN网络的Mnist数据集分类 1.数据的载入和预处理 import numpy as np from keras.datasets import mnist from keras. ...
- iOS -iOS9中提示框(UIAlertController)的常见使用
iOS 8 之前提示框主要使用 UIAlertView和UIActionSheet:iOS 9 将UIAlertView和UIActionSheet合二为一为:UIAlertController . ...
- 微信小程序 简单获取屏幕视口高度
由于小程序的宽度是固定的 750rpx,我们可以先用wx.getSystemInfo 来获取可使用窗口的宽高(并非rpx),结合750rpx的宽度算出比例,再用比例来算出高度 let that = t ...
- 一次性搞懂 PHP 中面向对象的所有知识点。
OOP是什么? OOP是面向对象编程,面向对象编程是一种计算机编程架构. OOP的基本原则是计算机程序是由单个能起到子程序作用的单元或对象组合而成. 基本概念: 类:定义了事务的抽象特点.包含了数据的 ...
- css布局相关:涉及到常见页面样式难点
一.display:table用法 Table:display:tableBody:table-row-group;Tr: table-row;Td: table-cell https://www.c ...
- 【大厂面试07期】说一说你对synchronized锁的理解?
synchronized锁的原理也是大厂面试中经常会涉及的问题,本文主要通过对以下问题进行分析讲解,来帮助大家理解synchronized锁的原理. 1.synchronized锁是什么?锁的对象是什 ...
- Java——int、double型数组常用操作工具类
学了数组之后,感觉有好多操作需要经常去写,很不方便,因此自己做了一个工具类,方便调用,方法可能不全,希望大家可以添加,让我使用也方便一点儿. public class ArrayUtils { //求 ...