码迷,mamicode.com
首页 > 其他好文 > 详细

codeforce F - Three Paths on a Tree

时间:2020-01-26 22:34:35      阅读:79      评论:0      收藏:0      [点我收藏+]

标签:ace   void   ble   imp   def   The   data-   specific   tmp   

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 (3n21053≤n≤2⋅105) — the number of vertices in the tree.

Next n1n−1 lines describe the edges of the tree in form ai,biai,bi (1ai1≤ai, binbi≤n, aibiai≠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 1a,b,cn1≤a,b,c≤n and a,bc,aca≠,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 相同的情况。

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=4e5+10;
 4 int head[maxn]; int num=-1;
 5 int dis[maxn];
 6 int tmp1[maxn],tmp2[maxn];
 7 int pos,ans;
 8 struct node
 9 {
10     int v,w;
11     int next;
12 }G[maxn];
13 void add(int u,int v,int w)
14 {
15     G[++num].v=v;G[num].w=w;G[num].next=head[u];head[u]=num;
16     G[++num].v=u;G[num].w=w;G[num].next=head[v];head[v]=num;
17 }
18 void dfs(int u,int fa)
19 {
20     if(dis[u]>ans){
21         ans=dis[u];
22         pos=u;
23     }
24     for(int i=head[u];i!=-1;i=G[i].next){
25         int v=G[i].v;
26         if(v==fa) continue;
27         dis[v]=dis[u]+G[i].w;
28         dfs(v,u);
29     }
30     return;
31 }
32 void init()
33 {
34     memset(head,-1,sizeof(head));
35     num=-1;
36 }
37 int main()
38 {
39     init();
40     int n;
41     scanf("%d",&n);
42     for(int i=1;i<n;i++){
43         int u,v;
44         scanf("%d%d",&u,&v);
45         add(u,v,1);
46     }
47     dfs(1,0);
48     memset(dis,0,sizeof(dis));
49     int p1=pos;
50     ans=0;
51     dfs(pos,0);
52     int p2=pos;
53     for(int i=1;i<=n;i++)
54         tmp1[i]=dis[i];
55     memset(dis,0,sizeof(dis));
56     dfs(pos,0);
57     for(int i=1;i<=n;i++)
58         tmp2[i]=dis[i];
59     pos=0;
60     for(int i=1;i<=n;i++){
61         if(tmp1[i]+tmp2[i]>tmp1[pos]+tmp2[pos]&&i!=p1&&i!=p2)
62             pos=i;
63     }
64     ans=(tmp1[p2]+tmp1[pos]+tmp2[pos])/2;
65     printf("%d\n",ans);
66     printf("%d %d %d\n",p1,p2,pos);
67     return 0;
68 }

 

codeforce F - Three Paths on a Tree

标签:ace   void   ble   imp   def   The   data-   specific   tmp   

原文地址:https://www.cnblogs.com/pangbi/p/12234819.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!