codeforce F - Three Paths on a Tree
2 seconds
256 megabytes
standard input
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.
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.
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.
给出一棵无权树(可理解为边权为 11 ),你需要选取三个点 a,b,ca,b,c ,最大化 a,ba,b 和 b,cb,c 和 a,ca,c 的简单路径的并集的长度。
输出这个最大长度和 a,b,ca,b,c 。
有一个结论:
必定会有一组最优解,使得 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的更多相关文章
- HDU 4912 Paths on the tree(LCA+贪心)
题目链接 Paths on the tree 来源 2014 多校联合训练第5场 Problem B 题意就是给出m条树上的路径,让你求出可以同时选择的互不相交的路径最大数目. 我们先求出每一条路径 ...
- hdu 4912 Paths on the tree(树链拆分+贪婪)
题目链接:hdu 4912 Paths on the tree 题目大意:给定一棵树,和若干个通道.要求尽量选出多的通道,而且两两通道不想交. 解题思路:用树链剖分求LCA,然后依据通道两端节点的LC ...
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
[题目]F. Imbalance Value of a Tree [题意]给定n个点的带点权树,求所有路径极差的和.n,ai<=10^6 [算法]并查集 [题解]先计算最大值的和,按点权从小到大 ...
- Codeforces 915 F. Imbalance Value of a Tree(并查集)
F. Imbalance Value of a Tree 题意: 给一颗带点权的树,求所有简单路径上最大点权和最小点权之差的总和. 思路: 所求问题可以看作求各路径上的最大值之和减各路径上的最小值之和 ...
- 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,求每个子树中最长的边,满 ...
- Codeforces.741D.Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree 思路)
题目链接 \(Description\) 给定一棵树,每条边上有一个字符(a~v).对每个节点,求它的子树中一条最长的路径,满足 路径上所有边上的字符可以重新排列成一个回文串.输出其最长长度. \(n ...
- [Codeforces741D]Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths——dsu on tree
题目链接: Codeforces741D 题目大意:给出一棵树,根为$1$,每条边有一个$a-v$的小写字母,求每个点子树中的一条最长的简单路径使得这条路径上的边上的字母重排后是一个回文串. 显然如果 ...
- Educational Codeforces Round 52 (Rated for Div. 2) F. Up and Down the Tree 树型DP
题面 题意:给你一棵树,你起点在1,1也是根节点,你每次可以选择去你子树的某个叶子节点,也可以选择,从叶子节点返回距离不超过k的一个根, 也就是说,你从1开始,向下跳,选择一个叶子(就是没有子树的节点 ...
- CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths——dsu on tree
题目描述 一棵根为1 的树,每条边上有一个字符(a-v共22种). 一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串. 求每个子树中最长的Dokhtar- ...
随机推荐
- javaweb 使用页面模板CSS或者Js修改失效的解决办法(Tomcat缓存问题)
原因是:浏览器的自动缓存机制导致的. 浏览器会自动缓存静态文件以加快访问速度,但是这导致了他不会再从服务器端接收静态文档了,这就导致我在idea里面改的css和js文档,浏览器根本没下载下来. 所以解 ...
- openlayers编辑区域
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Excel时间格合并(年月日+时间点)
=value(a1)+b2 日期 时间 合并 2018/8/8 14:13 2018/8/8 14:13:00
- Cobalt Strike配置及简单使用
前言 CS分为客户端与服务端,服务端是一个,客户端可以有多个,非常适合团队协同作战,多个攻击者可以同时连接到一个团队服务器上,共享攻击资源与目标信息和sessions,可模拟APT做模拟对抗,进行内网 ...
- 解决ios手机中input输入框光标过长的问题
修改前css部分代码: .receiving-info .receiving-info-list input { display: inline-block; width: 70%; font-siz ...
- Django 查看原生的sql语句
python manage.py sqlmigrate your_app_name 0001 把your_app_name换成自己的app名字即可看到框架自动生成的创建表sql语句,于是我就这样看到了 ...
- Ubuntu18.04安装mysql(AWS云)
1.执行如下三条命令 sudo apt-get install mysql-server sudo apt install mysql-client sudo apt install libmysql ...
- 使用pycharm搜索框和正则表达式匹配内容
使用pycharm搜索框和正则表达式匹配内容原创薯饼__ 最后发布于2019-03-04 19:28:53 阅读数 660 收藏展开有时候我们要在爬虫网站中匹配各种各样的文本块,以获取需要的信息,每一 ...
- PM2的参数配置
https://github.com/jawil/blog/issues/7 配置项: name 应用进程名称:script 启动脚本路径:cwd 应用启动的路径,关于script与cwd的区别 ...
- 转载:dsp芯片的定点运算
转自: http://ishare.iask.sina.com.cn/f/37179153.html