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] 逃学的小孩 题解的更多相关文章

  1. 洛谷 P4408 [NOI2003]逃学的小孩

    题目传送门 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚, ...

  2. 洛谷P4408 [NOI2003] 逃学的小孩 (树的直径)

    本题就是从c到a/b再到b/a距离的最大值,显然,a和b分别是树的直径的两个端点,先用两次dfs求出树的直径,再用一次dfs求出每个点到a的距离,最后再用一次dfs求出每个点到距离它较近的a/b的距离 ...

  3. [NOI2003]逃学的小孩 题解

    前言 >原题传送门(洛谷)< 看了一下洛谷题面,这道NOI的题竟然是蓝的(恶评?),做了一下好像确实是蓝的... 解法 思路非常简单,找道树的直径,然后答案是直径长度加上最大的min(di ...

  4. BZOJ1509 & 洛谷4408:[NOI2003]逃学的小孩——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=1509 https://www.luogu.org/problemnew/show/P4408 sb ...

  5. LUOGU P4408 [NOI2003]逃学的小孩(树的直径)

    题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:“喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?”一听说要考试,Chris的父母就心急如焚,他们决定在尽 ...

  6. luogu P4408 [NOI2003]逃学的小孩

    题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听说要考试,Chris的父母就心 ...

  7. 洛谷 P4408 逃学的小孩 解题报告

    P4408 [NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?&q ...

  8. 【BZOJ1509】[NOI2003]逃学的小孩 直径

    [BZOJ1509][NOI2003]逃学的小孩 Description Input 第一行是两个整数N(3  N  200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的 ...

  9. [NOI2003]逃学的小孩(树的直径)

    [NOI2003]逃学的小孩 题目描述 Chris家的电话铃响起了,里面传出了Chris的老师焦急的声音:"喂,是Chris的家长吗?你们的孩子又没来上课,不想参加考试了吗?"一听 ...

随机推荐

  1. 『Go基础』第8节 格式化输出

    输出就是将数据信息打印到电脑屏幕上. 本节我们就来学习一下Go语言中的三种输出方式: Print().Println().Printf(). 1.Print() Print()主要的一个特点就是打印数 ...

  2. LOJ2026 JLOI/SHOI2016 成绩比较 组合、容斥

    传送门 感觉自己越来越愚钝了qwq 先考虑从\(n-1\)个人里安排恰好\(k\)个人被碾压,然后再考虑如何分配分数,两者乘起来得到答案. 对于第一部分,可以考虑容斥:设\(f_i\)表示\(i\)个 ...

  3. node.js开发 1-概述

    https://www.cnblogs.com/gaoya666/p/9071288.html Nodejs英文网:https://nodejs.org/en/ 中文网:http://nodejs.c ...

  4. 可拖拽dialog

    指令的封装转自https://blog.csdn.net/sinat_21902709/article/details/86545444 可拖拽dialog应用于很多弹出框,所以需要作用于全局 在插件 ...

  5. spring boot 集成mybatis plus 含分页 完整教程

    一.添加依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus ...

  6. Mycat分布式数据库架构解决方案--Server.xml详解

    echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! 该文件 ...

  7. Js保存图片到本地

    注:此方法是使用hbuilderx云打包之后才能用,否则在浏览器中会报 plus is not defined 官方文档 http://www.html5plus.org/doc/zh_cn/gall ...

  8. Java 之 数据库连接池

    一.数据库连接池 1.连接池概念 连接池其实就是一个容器(集合),存放数据库连接的容器. 当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问之 ...

  9. Android应用通过JDBC直连阿里云MySQL数据库

    1.设置白名单,获取外网连接地址 外部设备要访问阿里云MySQL数据库,则需要设置白名单,具体操作链接: https://help.aliyun.com/document_detail/43185.h ...

  10. iptables详细介绍

    iptables简介 netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火 ...