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 ;
}

最新文章

  1. Linq To SQL 的问题点滴
  2. 移动端框架篇-控制子容器的滑屏框架-fullPage.js
  3. 关于不断刷新界面jsp+ajax
  4. OC-copy
  5. chmod() has been disabled for security reasons
  6. 容易答错的JS笔试题
  7. javaee基本环境搭建
  8. common tar command
  9. Scope and Namespace
  10. Bootstrap 开关(switch)使用整理
  11. [Swift]LeetCode339. 嵌套链表权重和 $ Nested List Weight Sum
  12. 爬坑!OpenCV打开双目摄像头
  13. python爬百度文库课件
  14. springboot指定端口的三种方式
  15. JSP数据库插入判断
  16. jira6.3.6创建问题不自动发邮件通知的问题
  17. Robust Influence Maximization
  18. sql 语句的limit的用法
  19. 011-ThreadFactory线程工厂
  20. 记录一则expdp任务异常处理案例

热门文章

  1. mongodb 基础入门教程
  2. JAVA方法中参数到底是值传递还是引用传递
  3. openlayers轨迹匀速播放
  4. 分布式集群HA模式部署
  5. HTML5,从零开始
  6. Java架构师资料
  7. pytest+requests+Python3.7+yaml+Allure+Jenkins+docker实现接口自动化测试
  8. 0级搭建类010-Oracle Linux 6.x安装(OEL 6.10) 公开
  9. react-React深入-一等公民-props-onChange
  10. jenkins - docker搭建jenkins