洛谷 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的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听 ...
随机推荐
- PHP提取中英文首字母的方法(首字母索引)
function Getzimu($str) { $str= iconv("UTF-8","gb2312", $str);//如果程序是gbk的,此行就要注释掉 ...
- Django-03-静态文件配置
一.django静态文件配置原理 静态文件配置就是为了让用户请求时django服务器能找到静态文件返回. 首先要理解几个概念: 媒体文件:用户上传的文件 静态文件:css,js,image等 开发环境 ...
- Nmap脚本使用
Nmap是主机扫描工具,他的图形化界面是Zenmap,分布式框架为Dnamp. Nmap可以完成以下任务: 主机探测 端口扫描 版本检测 系统检测 支持探测脚本的编写 Nmap在实际中应用场合如下: ...
- flask报错 KeyError: <flask.cli.ScriptInfo object at 0x000001638AC164E0>
(flask_venv) D:\DjangoProject\flask_test>flask db init Traceback (most recent call last): File &q ...
- prometheus grafana graylog 钉钉告警 短信告警 电话告警系统 PrometheusAlert
PrometheusAlert 简介 PrometheusAlert是开源的运维告警中心消息转发系统,支持主流的监控系统Prometheus,日志系统Graylog和数据可视化系统Grafana发出的 ...
- Spring Cloud Stream如何消费自己生产的消息
在上一篇<Spring Cloud Stream如何处理消息重复消费>中,我们通过消费组的配置解决了多实例部署情况下消息重复消费这一入门时的常见问题.本文将继续说说在另外一个被经常问到的问 ...
- lombok工具插件安装(idea、eclipse)
https://blog.csdn.net/Y_hahaha/article/details/89186284 缘由,项目在IDEA下@Data.@Builder注解不起作用.发现是lombok这 ...
- 作业调度框架Quartz.NET-现学现用-01-快速入门
原文:作业调度框架Quartz.NET-现学现用-01-快速入门 前言 你需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后一天执行.一个自动执行而无须干预的任务在执 ...
- java之hibernate之单向的一对多关联映射
这篇主要讲hiberante中的 单向一对多关联映射 1.在应用中,有时候需要从一的一端获取多的一端的数据.比如:查看某个分类下的所有书籍信息:查看某个订单下的所有商品等. 2.在一对多的关联关系中, ...
- 一张图看懂SharpImage
通过下面的图片,可以瞬间看懂整个类库的脉络.图片比较大,如果看不清,可