洛谷 P4408 [NOI2003] 逃学的小孩 题解
Analysis
题意虽然说先去谁家再去谁家,但是我们不需要管这个,因为AA、BB、CC三个点我们可以任意互相交换它们所代表的对象,所以题目要求的就是在一棵树上找到3个点AA、BB、CC令AB+BCAB+BC最大,同时要满足AC>ABAC>AB。
由于这是一棵树,它满足非常可爱的性质,就是如果找一个点出去两条路径使它们的合最大,那么一条是直径时一定会存在一种最大的方案。
所以我们可以使要找的两条路径其中一条是直径(设为ABAB),然后枚举剩下的点,找到一个到达直径端点最长的另一条路径,不过因为题目要满足一个AC>ABAC>AB,所以我们需要在每次枚举的时候(设为CC),选择ACAC和BCBC的较小的一条边作为另一条路径。可以看到,若是ACAC是小于BCBC的,则选择的路径是ACAC,实际走的路线是CACA+ABAB,满足题目要求的CA<CBCA<CB,而若是选择的是BCBC,实际路线是CBCB+BABA,也符合题意要求的CB<CACB<CA。
至此,就可以写出代码了,跑2遍dfs找出直径,再对直径起点和终点跑出对每个点的路径长度,然后计算答案。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define maxn 200000+10
using namespace std;
inline int read()
{
int x=;
bool f=;
char c=getchar();
for(; !isdigit(c); c=getchar()) if(c=='-') f=;
for(; isdigit(c); c=getchar()) x=(x<<)+(x<<)+c-'';
if(f) return x;
return -x;
}
inline void write(int x)
{
if(x<){putchar('-');x=-x;}
if(x>)write(x/);
putchar(x%+'');
}
int n,m,cnt,com,sta,ed,ans;
int dis1[maxn],dis2[maxn],head[*maxn];
struct node
{
int to,val,nxt;
}edge[*maxn];
inline void add(int x,int y,int z)
{
cnt++;
edge[cnt].to=y;
edge[cnt].val=z;
edge[cnt].nxt=head[x];
head[x]=cnt++;
}
inline void dfs1_tree_d(int x,int fa)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fa) continue;
dis1[to]=dis1[x]+edge[i].val;
if(dis1[to]>com)
{
com=dis1[to];
sta=to;
}
dfs1_tree_d(to,x);
}
}
inline void dfs2_tree_d(int x,int fa)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fa) continue;
dis2[to]=dis2[x]+edge[i].val;
if(dis2[to]>com)
{
com=dis2[to];
ed=to;
}
dfs2_tree_d(to,x);
}
}
inline void find1_long(int x,int fa)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fa) continue;
dis1[to]=dis1[x]+edge[i].val;
find1_long(to,x);
}
}
inline void find2_long(int x,int fa)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int to=edge[i].to;
if(to==fa) continue;
dis2[to]=dis2[x]+edge[i].val;
find2_long(to,x);
}
}
signed main()
{
// freopen("truant.in","r",stdin);
// freopen("truant.out","w",stdout);
n=read();m=read();
for(int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
add(x,y,z);
add(y,x,z);
}
com=;
dfs1_tree_d(,);
com=;
dfs2_tree_d(sta,);
ans=dis2[ed];
memset(dis1,,sizeof(dis1));
memset(dis2,,sizeof(dis2));
find1_long(sta,);
find2_long(ed,);
com=;
for(int i=;i<=n;i++)
{
int len=min(dis1[i],dis2[i]);
if(len>com) com=len;
}
ans+=com;
write(ans);
return ;
}
请各位大佬斧正(反正我不认识斧正是什么意思)
洛谷 P4408 [NOI2003] 逃学的小孩 题解的更多相关文章
- 洛谷 P4408 [NOI2003]逃学的小孩
题目传送门 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚, ...
- 洛谷P4408 [NOI2003] 逃学的小孩 (树的直径)
本题就是从c到a/b再到b/a距离的最大值,显然,a和b分别是树的直径的两个端点,先用两次dfs求出树的直径,再用一次dfs求出每个点到a的距离,最后再用一次dfs求出每个点到距离它较近的a/b的距离 ...
- [NOI2003]逃学的小孩 题解
前言 >原题传送门(洛谷)< 看了一下洛谷题面,这道NOI的题竟然是蓝的(恶评?),做了一下好像确实是蓝的... 解法 思路非常简单,找道树的直径,然后答案是直径长度加上最大的min(di ...
- BZOJ1509 & 洛谷4408:[NOI2003]逃学的小孩——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1509 https://www.luogu.org/problemnew/show/P4408 sb ...
- LUOGU P4408 [NOI2003]逃学的小孩(树的直径)
题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚,他们决定在尽 ...
- luogu P4408 [NOI2003]逃学的小孩
题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听说要考试,Chris的父母就心 ...
- 洛谷 P4408 逃学的小孩 解题报告
P4408 [NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?&q ...
- 【BZOJ1509】[NOI2003]逃学的小孩 直径
[BZOJ1509][NOI2003]逃学的小孩 Description Input 第一行是两个整数N(3 N 200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的 ...
- [NOI2003]逃学的小孩(树的直径)
[NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听 ...
随机推荐
- 用Python递归做个多层次的文件执行
想用 递归实现多层次的 '.py'执行但是发现好像不能 import os def func(path): if os.path.isdir(path): for name in os.listdir ...
- HTML-点击Div读取本地文件内容
<!DOCTYPE html> <html> <div id="container" onclick="choosefile();" ...
- 颜色转换、随机、16进制转换、HSV
颜色转换.随机.16进制转换.HSV: /** * * *-----------------------------------------* * | *** 颜色转换.随机.16进制转换.HSV * ...
- 单例DCL模式
单例模式可以保证系统中一个类只有一个实例.即一个类只有一个对象实例. 一般写法 public class DCLSingle { public static DCLSingle instance= n ...
- java之servlet之文件下载
1.在页面中,可以直接通过超链接来下载: a) 如果浏览器能够打开该文件,那么直接在浏览器中显示---不是想要的效果 b) 任何人都能下载,不能进行权限控制 2.通过servlet来进行下载,在ser ...
- Thomas Brinkhoff 基于路网的移动对象生成器的使用[第二版]
Thomas Brinkhoff 基于路网的移动对象生成器的使用 Thomas Brinkhoff 基于路网的移动对象生成器的使用 相关操作的说明 相关文件的说明 运行 导入eclipse后运行时选择 ...
- 前端开发 vue,angular,react框架对比1
转载自:https://www.cnblogs.com/hubgit/p/6633214.html 首先,我们先了解什么是MVX框架模式? MVX框架模式:MVC+MVP+MVVM 1.MVC:Mod ...
- 3:基于乐观锁(两种)控制并发: version、external锁
ES是基于乐观锁进行并发控制的. 如果有并发的业务场景,可以直接使用ES内置乐观锁机制. 使用的时候,java程序需要先Get指定的记录,获取到版本号,然后Put的时候,带着该版本号,请求更新. ES ...
- 利用PHPExcel快速导出excel
<?php $objPHPExcel = new PHPExcel(); $objSheet = $objPHPExcel->getActiveSheet(); $array = arra ...
- 关于Eclipse导入maven项目报空指针异常
今天新建了一个maven项目,因为是通过公司的工具新建的,代码拉下来就有src.pom.xml文件. 导入Eclipse却报空指针异常.具体如下: An error has occurred. See ...