[Simulator 10.12] Boss Title description
Because OB won 4 gold medals this year, the school sponsored the extension of the Office of the workers as the Workers Office group, in order to reflect the characteristics of OI, office groups were designed to be tree-shaped (n point n? 1-side undirected connectivity graph), because the new office is so big that the trophy must be divided in two different places so that the students throw coins into the turn, OB would like to ask you to help him see where the trophy in the two offices so that any one in the office of the work of the children can find the fastest trophy to be set.
Sentence Test instructions: give a tree of n points, place trophies at two suitable and different points, and minimize the maximum distance from each point to the nearest trophy.
Input
The first line, an integer n.
The next n? 1 rows, two numbers per line x y
Output
A number that represents the minimum maximum distance.
Sample input
8
1 2
1 3
2 4
2 5
3 6
3 7
1 8
Sample output
2
Tips
For the first 60% data, n≤100.
For the first 80% data, n≤2000.
For 80% of the data, the tree shape is guaranteed to be random.
For 100% of data, ensure 3≤n≤200000.
Solution
This problem solves a lot of methods, however Bo master Konjac konjac only (O (n\log n) \) Practice
So where exactly do these two trophies go? To prove that it must be in the diameter of the tree.
Simple talk.
This is about the nature of the diameter of the tree: the diameter of the tree is the longest path on the tree, and any point in the tree from its farthest point must be a vertex of the diameter of the tree.
Assuming that the trophy is in the diameter of the tree to meet the conditions, then we must at least ensure that it can cover at least one of the diameter of the end , otherwise it certainly does not satisfy the condition, since it can meet the endpoint, then must be able to meet the diameter of the point of the sub-tree nodes, Unless the deepest depth of a tree is farther than its distance from the end of the diameter, it violates the nature of the diameter, so it is assumed
Know the two points in the diameter, how to know their distance from the diameter of it? Because the distance between the two points from the end of the diameter must be the maximum distance to meet the premise of test instructions, we want to make this distance to the smallest, can be two minutes this distance, then go to \ (O (n) \) Verification
How to verify, is that I started to say the nature, first find the two nodes, and then find the two nodes between the interval of each subtree, see not in the diameter of the node's maximum depth is not more than our two points of this mid
The code in the examination room hastily, a little ugly, will look at it ~ ~
I heard that this problem can also be tree-shaped DP \ (O (n) \) do, here to paste the solution of the various practices
\ (3.1\ 60\% O (n^3) \)
\ (n^2\) enumerates two trophy positions, then \ (O (n) \) sweep over to see how far each position is from the nearest trophy.
\ (3.2\ 80\% O (n^2) \)
Consider that the two trophy area must have a boundary, we enumerate the boundary, which is an edge, part of which is a subtree, part of the subtree, we only need to find the diameter of the other two trees separately.
\ (3.3\) tree pattern random
The diameter of the desired tree is very short, and two trophies are enumerated on the diameter.
\ (3.4\ 100\%\) Two-point answer 1 \ (O (NLOGN) \)
The trophy is on the diameter, and after the two answers, take the distance from the end of the diameter to the point of the answer and traverse the check again.
\ (3.5\ 100\%\) Two-point answer 2 \ (O (NLOGN) \)
Casually mention a node as the root, two-point answer, the deepest depth of the node must be taken care of, so the deepest point upward jump to the answer layer can be, and its distance from the point of the answer are deleted, and then do once.
This method can be extended to the K trophy, courtesy of Pipi.
\ (3.6\ 100\%\) tree dp\ (\ O (n) \)
With a tree DP on a 80-point basis, note the length of the longest path of the subtree without returning the first three long and up one. The diameter of the subtree is the first two long and with each subtree of the subtree the diameter of max; the outer diameter of the subtree is the longest path length of the subtree without returning to the child tree, and the first two lengths do not go to the longest downward path of the subtree. This three takes the first two lengths plus the answers above the parent node to take Max.
Code
#include <bits/stdc++.h> #define RG register#define il inline#define Min (a) (a) < (b)? (a):(B) #define MAX (a) (a) > (b)? (a):(b) #define LOL long long#define in (i) (I=read ()) using namespace Std;const int N=2e5+10;int read () {int ans=0,f=1; Char I=getchar (); while (i< ' 0 ' | | i> ' 9 ') {if (i== '-') f=-1; I=getchar ();} while (i>= ' 0 ' && i<= ' 9 ') ans= (ans<<1) + (ans<<3) +i-' 0 ', I=getchar (); return ans*=f;} int N,cur,s,t;int to[n<<1],nex[n<<1],head[n];int dis[n],f[n],son[n],vis[n],dep[n];void Add (int a,int b) { To[++cur]=b,nex[cur]=head[a],head[a]=cur; To[++cur]=a,nex[cur]=head[b],head[b]=cur;} void Dfs (int u,int fa) {F[U]=FA; for (int i=head[u];i;i=nex[i]) {if (TO[I]==FA) continue; dis[to[i]]=dis[u]+1; DFS (TO[I],U); }}int dfs2 (int u,int ans=1) {dep[u]=dis[u]; for (int i=head[u];i;i=nex[i]) {if (To[i]==f[u] | | vis[to[i]]) continue; DFS2 (To[i]); Dep[u]=max (Dep[u],dep[to[i]); }return ans;} BOOL Check (int mid) {int a=s,b=t; while (a!=t) {if (dis[a]-dis[s]==mid) break; A=son[a]; } while (B!=s) {if (dis[t]-dis[b]==mid) break; B=F[B]; } if (Dis[b]-dis[a]>2*mid) return 0; int ll=a,rr=b; while (a!=b && b) {DFS2 (b); int aq=dep[b]-dis[b]; if (min (dis[b]-dis[ll],dis[rr]-dis[b)) +aq>mid) return 0; B=F[B]; } DFS2 (b); int aq=dep[b]-dis[b]; if (min (dis[b]-dis[ll],dis[rr]-dis[b)) +aq>mid) return 0; return 1;} int main () {//freopen ("ob.in", "R", stdin); Freopen ("Ob.out", "w", stdout); In (n); for (int. i=1,a,b;i<n;i++) in (a), in (b), add (A, a,); DFS (1,0); for (int i=1;i<=n;i++) if (Dis[i]>dis[s]) s=i; memset (dis,0,sizeof (dis)); DFS (s,0); for (int i=1;i<=n;i++) if (dis[i]>dis[t]) t=i; int id=t; while (ID) vis[id]=1,son[f[id]]=id,id=f[id]; Vis[s]=vis[t]=1; int l=0,r=dis[t]; while (l<r) {int mid=l+r>>1; if (check (mid)) r=mid; else l=mid+1; }cout<<r<<endl;}
[Simulator 10.12] Boss (binary/tree diameter/tree DP)