[The diameter of the tree] F. Three Paths on a Tree

F. Three Paths on a Tree

Description

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 ccis 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, bb and 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.

Examples

Input

8
1 2
2 3
3 4
4 5
4 6
3 7
3 8

Output

5
1 8 6

Note

The picture corresponding to the first example (and another one correct answer):

If you choose vertices 1,5,61,5,6 then the path between 11 and 55 consists of edges (1,2),(2,3),(3,4),(4,5)(1,2),(2,3),(3,4),(4,5), the path between 11 and 66 consists of edges (1,2),(2,3),(3,4),(4,6)(1,2),(2,3),(3,4),(4,6) and the path between 55 and 66 consists of edges (4,5),(4,6)(4,5),(4,6). The union of these paths is (1,2),(2,3),(3,4),(4,5),(4,6)(1,2),(2,3),(3,4),(4,5),(4,6) so the answer is 55. It can be shown that there is no better answer.

Correct solution:

Elected three points in the trees, so their edges and set maximum.

This introduces the diameter of the tree, the diameter of the longest side of the tree. Suppose a, b is the diameter of the two end points of the tree, c is in addition to a, b to any point in

years = (say (a, c) + say (a, b) + said (b, c)) / 2;

BFS seeking twice the diameter of the tree with the endpoint:

So the question is, how do find the diameter of the tree? BFS provided herein applies a two-way tree diameter requirements:

 Optionally a first starting end BFS find the longest path, then from the end BFS, the second path is the BFS tree to find the longest diameter;
 principle: the starting point is set u, v first end BFS Found is a certain end diameter of the tree
 demonstrated: 1) If u is a point on the diameter, the diameter of the end is apparently v (v because if not, then there must be another point such that u to w w greater distance, then to BFS found v contradictory)
     2) If a point on u not a diameter, then u diameter v is bound to a tree intersect (evidence to the contrary), then the intersection of the inevitable is half of the diameter v of the
 so v must be the diameter an endpoint, it is obtained from v BFS diameter length must be

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <algorithm>
 5 #include <set>
 6 #include <queue>
 7 #include <stack>
 8 #include <string>
 9 #include <cstring>
10 #include <vector>
11 #include <map>
12 //#include <unordered_map>
13 #define mem( a ,x ) memset( a , x ,sizeof(a) )
14 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
15 #define lson  l ,mid ,pos<<1
16 #define rson mid+1 ,r ,pos<<1|1
17 using namespace std;
18 typedef long long ll ;
19 typedef pair<int ,int> pii;
20 typedef pair<ll ,int> pli;
21 const int inf = 0x3f3f3f3f;
22 const ll mod=998244353;
23 const int N=1e5+50;
24 int n,xx,yy,pos;
25 int Link[2*N],len=0,bok[2*N],dis[2*N];
26 int dis1[2*N],dis2[2*N];
27 int que[2*N];
28 struct node
29 {
30     int y,next;
31 }e[4*N];
32 void insert(int xx,int yy)
33 {
34     e[++len].next=Link[xx];
35     Link[xx]=len;
36     e[len].y=yy;
37 }
38 void dfs(int x)
39 {
40     for(int i=1;i<=n;i++)
41         bok[i]=0,dis[i]=inf;
42     bok[x]=1,dis[x]=0;
43     int head=1,tail=2;
44     que[1]=x;
45     pos=x;
46     while(head<tail)
47     {
48         int u=que[head];
49         for(int i=Link[u];i;i=e[i].next)
50         {
51             int v=e[i].y;
52             if(bok[v])  continue;
53             bok[v]=1;
54             if(dis[v]>dis[u]+1)
55             {
56                 dis[v]=dis[u]+1;
57                 que[tail++]=v;
58             }
59             if(dis[v]!=inf&&dis[v]>dis[pos])
60                 pos=v;
61         }
62         head++;
63     }
64 }
65 int main()
66 {
67     scanf("%d",&n);
68     for(int i=1;i<n;i++)
69     {
70         scanf("%d%d",&xx,&yy);
71         insert(xx,yy);
72         insert(yy,xx);
73     }
74     int a,b,c=0;
75     dfs(1),a=pos;
76     dfs(pos),b=pos;
77     for(int i=1;i<=n;i++)   dis1[i]=dis[i];
78     //cout<<a<<endl;
79     dfs(pos);
80     for(int i=1;i<=n;i++)   dis2[i]=dis[i];
81     //cout<<b<<endl;
82     int ans=0;
83     for(int i=1;i<=n;i++)
84     {
85         if(i==a||i==b)  continue;
86         if(ans<dis1[i]+dis2[i])
87         {
88             ans=dis1[i]+dis2[i];
89             c=i;
90         }
91     }
92     //cout<<c<<endl;
93     printf("%d\n",(ans+dis1[b])/2);
94     printf("%d %d %d\n",a,b,c);
95  
96      return  0 ;
97 }
View Code

------------------------------------------------------------------------------------------------------

DP tree

For each node we want to record two values:

F1 [i] denotes the subtree rooted at i, the leaf node i to a maximum value of the distance

F2 [i] denotes the subtree rooted at i, i is the leaf nodes of the second largest value from

For a node, the leaf node from which the maximum value and the secondary path through which substantially is certainly not the same

If j is the son i, then (below W [i] [j] denotes the path length of i to j):

If f1 [i] <f1 [j ] + w [i] [j], f2 [i] = f1 [i], [i] = [j] + w [i] f1 f1 [j];
otherwise, if f2 [i] <[j]  + w [i] f1 [j], f2 [i] = f1 [j] + w [i] [j];
appreciated: this is done, updates can look at the maximum value, If we can, it's the second largest value is the maximum value of the original, and then update its maximum; if not, see if I can update the second largest value, if, you update, you can not leave it there

In this case, the final answer answer = max {f1 [i] + f2 [i]}

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=100005;
 6 int n,m,t,ans;
 7 int f1[N],f2[N];
 8 int first[N],v[N],w[N],next[N];
 9 void add(int x,int y,int z)
10 {
11     t++;
12     next[t]=first[x];
13     first[x]=t;
14     v[t]=y;
15     w[t]=z;
16 }
17 void dp(int x,int father)
18 {
19     int i,j;
20     for(i=first[x];i;i=next[i])
21     {
22         j=v[i];
23         if(j==father)
24           continue;
25         dp(j,x);
26         if(f1[x]<f1[j]+w[i])
27         {
28             f2[x]=f1[x];
29             f1[x]=f1[j]+w[i];
30         }
31         else if(f2[x]<f1[j]+w[i])
32           f2[x]=f1[j]+w[i];
33         ans=max(ans,f1[x]+f2[x]);
34     }
35 }
36 int main()
37 {
38     int x,y,z,i;
39     scanf("%d%d",&n,&m);
40     for(i=1;i<=m;++i)
41     {
42         scanf("%d%d%d",&x,&y,&z);
43         add(x,y,z);
44         add(y,x,z);
45     }
46     dp(1,0);
47     printf("%d",ans);
48     return 0;
49 }
View Code

 

Guess you like

Origin www.cnblogs.com/Kaike/p/12302102.html