F. Three Paths on a Tree
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given an unweighted tree with nn vertices. Recall that a tree is a connected undirected graph without cycles.

Your task is to choose three distinct vertices a,b,ca,b,c on this tree such that the number of edges which belong to at least one of the simple paths between aa and bb, bb and cc, or aa and cc is the maximum possible. See the notes section for a better understanding.

The simple path is the path that visits each vertex at most once.

Input

The first line contains one integer number nn (3≤n≤2⋅1053≤n≤2⋅105) — the number of vertices in the tree.

Next n−1n−1 lines describe the edges of the tree in form ai,biai,bi (1≤ai1≤ai, bi≤nbi≤n, ai≠biai≠bi). It is guaranteed that given graph is a tree.

Output

In the first line print one integer resres — the maximum number of edges which belong to at least one of the simple paths between aa and bb, bband cc, or aa and cc.

In the second line print three integers a,b,ca,b,c such that 1≤a,b,c≤n1≤a,b,c≤n and a≠,b≠c,a≠ca≠,b≠c,a≠c.

If there are several answers, you can print any.

DescriptionDescription

给出一棵无权树(可理解为边权为 11 ),你需要选取三个点 a,b,ca,b,c ,最大化 a,ba,b 和 b,cb,c 和 a,ca,c 的简单路径的并集的长度。

输出这个最大长度和 a,b,ca,b,c 。

SolutionSolution

有一个结论:

必定会有一组最优解,使得 a,ba,b 是树直径上的端点。

这个结论我现在暂时不会证明,大家可以去看看其他 dalaodalao 的证明或是自己给出证明 >v<>v< 。

那我们可以套路地去把树直径两端点求出来,这里不推荐用 树形dp ,推荐大家用 两次搜索 求出树直径端点。

确定了 a,ba,b ,接下来我们只要去找到最优的 cc ,就可以最大化答案了。

此时我们注意到:a,ba,b 和 b,cb,c 和 a,ca,c 的简单路径的并集的长度其实就是 dis(a,b)+dis(b,c)+dis(a,c)2dis(a,b)+dis(b,c)+dis(a,c)2 。

此时 dis(a,b)dis(a,b) 已经确定了,当 dis(b,c)+dis(a,c)dis(b,c)+dis(a,c) 的值取到最大,那么整个式子取最大。

把 a,ba,b 到所有点的简单路径距离求出来,去枚举这个最优的 cc 即可,枚举的过程中记得判与 a,ba,b 相同的情况。

 #include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+;
int head[maxn]; int num=-;
int dis[maxn];
int tmp1[maxn],tmp2[maxn];
int pos,ans;
struct node
{
int v,w;
int next;
}G[maxn];
void add(int u,int v,int w)
{
G[++num].v=v;G[num].w=w;G[num].next=head[u];head[u]=num;
G[++num].v=u;G[num].w=w;G[num].next=head[v];head[v]=num;
}
void dfs(int u,int fa)
{
if(dis[u]>ans){
ans=dis[u];
pos=u;
}
for(int i=head[u];i!=-;i=G[i].next){
int v=G[i].v;
if(v==fa) continue;
dis[v]=dis[u]+G[i].w;
dfs(v,u);
}
return;
}
void init()
{
memset(head,-,sizeof(head));
num=-;
}
int main()
{
init();
int n;
scanf("%d",&n);
for(int i=;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v,);
}
dfs(,);
memset(dis,,sizeof(dis));
int p1=pos;
ans=;
dfs(pos,);
int p2=pos;
for(int i=;i<=n;i++)
tmp1[i]=dis[i];
memset(dis,,sizeof(dis));
dfs(pos,);
for(int i=;i<=n;i++)
tmp2[i]=dis[i];
pos=;
for(int i=;i<=n;i++){
if(tmp1[i]+tmp2[i]>tmp1[pos]+tmp2[pos]&&i!=p1&&i!=p2)
pos=i;
}
ans=(tmp1[p2]+tmp1[pos]+tmp2[pos])/;
printf("%d\n",ans);
printf("%d %d %d\n",p1,p2,pos);
return ;
}

codeforce F - Three Paths on a Tree的更多相关文章

  1. HDU 4912 Paths on the tree(LCA+贪心)

    题目链接 Paths on the tree 来源  2014 多校联合训练第5场 Problem B 题意就是给出m条树上的路径,让你求出可以同时选择的互不相交的路径最大数目. 我们先求出每一条路径 ...

  2. hdu 4912 Paths on the tree(树链拆分+贪婪)

    题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LC ...

  3. 【CodeForces】915 F. Imbalance Value of a Tree 并查集

    [题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...

  4. Codeforces 915 F. Imbalance Value of a Tree(并查集)

    F. Imbalance Value of a Tree 题意: 给一颗带点权的树,求所有简单路径上最大点权和最小点权之差的总和. 思路: 所求问题可以看作求各路径上的最大值之和减各路径上的最小值之和 ...

  5. CF 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [dsu on tree 类似点分治]

    D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths CF741D 题意: 一棵有根树,边上有字母a~v,求每个子树中最长的边,满 ...

  6. Codeforces.741D.Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree 思路)

    题目链接 \(Description\) 给定一棵树,每条边上有一个字符(a~v).对每个节点,求它的子树中一条最长的路径,满足 路径上所有边上的字符可以重新排列成一个回文串.输出其最长长度. \(n ...

  7. [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree

    题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...

  8. Educational Codeforces Round 52 (Rated for Div. 2) F. Up and Down the Tree 树型DP

    题面 题意:给你一棵树,你起点在1,1也是根节点,你每次可以选择去你子树的某个叶子节点,也可以选择,从叶子节点返回距离不超过k的一个根, 也就是说,你从1开始,向下跳,选择一个叶子(就是没有子树的节点 ...

  9. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths——dsu on tree

    题目描述 一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar- ...

随机推荐

  1. NOI Online能力测试游记:退役选手的自娱自乐

    2020年2月17日早上8点,CCF发布了关于举办NOI Online能力测试的通知. 为给选手提供一个锻炼的机会,CCF拟举办一场NOI Online能力测试.测试分为入门组和提高组,每组限额报名3 ...

  2. C 库函数 - fmod()

    C 库函数 - fmod() 转自: C 标准库 - <math.h> 描述 C 库函数 double fmod(double x, double y) 返回 x 除以 y 的余数. 声明 ...

  3. go语言 base58编码解码

    package main import ( "bytes" "encoding/hex" "fmt" "math/big" ...

  4. [ZJOI2009] 狼与羊的故事 - 最小割

    给定一个\(N \times M\)方格矩阵,每个格子可在\(0,1,2\)中取值.要求在方格的边上进行划分,使得任意联通块内不同时包含\(1\)和\(2\)的格子. ________________ ...

  5. Unity网络通讯(一)获取计算机的MAC地址

    1 string GetMac() { string mac = ""; mac = GetMacAddressBySendARP(); return mac; } [DllImp ...

  6. SpringMVC 源代码深度解析 IOC容器(Bean 解析、注册)

    SpringMVC通过一个配置文件描述Bean以及Bean之间的依赖关系,利用Java的反射机制实例化Bean并建立Bean之间的依赖关系.IOC容器在完成这些底层工作的基础还提供了Bean的实例缓. ...

  7. python3函数的参数

    函数的定义能简化代码的逻辑,对于函数的调用者来说,只需要知道如何正确的传递参数,以及知道函数将返回什么值就可以了,而函数内部的复杂逻辑被封装起来,调用者不必了解. 位置参数 调用函数时,传入实参的值按 ...

  8. STM 32 内部功能回顾

    EXTI   外部中断 NVIC 嵌套的向量式中断控制器 AHB 是高级高性能内部总线,主要是用在CPU.DMA.DSP(数字信号处理) APB 是外围总线,I2C. 串口 APB 分为高速APB2( ...

  9. dmesg用法

    百科概念:dmesg是一种程序,用于检测和控制内核环缓冲.程序用来帮助用户了解系统的启动信息. 解释:dmesg命令显示linux内核的环形缓冲区信息,我们可以从中获得诸如系统架构.cpu.挂载的硬件 ...

  10. linux交互执行命令,expect

    转载 http://donex.blog.51cto.com/2005970/834467 原文比较乱,只能参考 本地交互执行: 1. 修改shell#!/usr/bin/expectset USER ...