Question C: "Usaco2010 Dec" cow aerobics O (∩_∩) O

Title Description

Farmer John in order to keep the cows healthy, let the poor cows kept in a small road running between the ranch. These cows path set may be represented as a set of points and a number of bi-directional path connecting two vertices, so that between each pair of points exactly a simple path. 
Simply put, the layout of these points is a tree, and each side of equal length, is 1. For a given set of a cow path, smart cows calculates the value of any point on the path, which we call the diameter of the path of the collection. If the diameter is too large, the cows will refuse to exercise. Farmer John every point labeled 1..V (2 <= V <= 100,000). In order to obtain a more short diameter, he can choose to block some of the existing road, so you can get more set of paths, thereby reducing the diameter of some paths set. We start with a tree, FJ can choose to block S (1 <= S <= V-1) bidirectional path, so as to obtain a set of S + 1 paths. You have to do is calculate the best blocking scheme, so that all the paths he got the set maximum diameter as small as possible.  
Farmer John tell you all V-1 two-way road, each expressed as: vertex A_i (1 <= A_i <= V) and B_i (1 <= B_i <= V; A_i = B_i!) Connection.  
Let's look at the following example: linear path set (7 trees vertices). 3. 1 --- 2 --- --- ---. 4. 5. 6 --- --- 7 If two FJ can block road, his possible choices are as follows: 1 --- 2 | 3 --- 4 | 5 --- 6 --- 7 so that the longest diameter is 2, that is the best answer (of course not the only one). 

Entry

Line 1: an integer of two space-separated S V and  
the second 2 ~ V lines: two spaces separated integers A_i and B_i 

Export

Output Line 1: an integer, it indicates the maximum diameter that can be obtained FJ.

Sample input  Copy

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

Sample output Copy

2 

ideas:
  • This question still feel very good thought, a kind of see how the most value, is something like two-thirds of the first reaction, and then to find the transfer of some state, then it is easy to think of DP.
  • We half the minimum value, and then verify that it is valid, i.e. the answer to ensure maximum chain length of not greater than two minutes

  • We set DP [ i ] expressed in the first i subtree rooted at node i, the legitimate end points longest chain length of the chain does not cross the path of the root

  • Then we can use dp [i] calculate how many edges to be cut off in order to determine the current separation of the two answers legitimacy

  • Although the feeling is very simple, but think carefully found a transfer is not so easy to play

  • Obviously determined directly m A X ( F [ S O n- ] ) is not feasible, because it does not guarantee legitimate, but we think, when we selected two sons where longest chain extremities of the path does not cross the root node chain, found them together at the time when the length is too large, cut off from the needs, you will find only two cases

  • The longest side chain to cut the top of the best (if cut edges are not top of the chain, or cut short the chain, then there may be other unlawful situation, still have to cut once)

  • After the cut, it will not affect the parent node (due after the cut end, these two points are not in a communication block, the course will not be affected).

  • So far this problem can be substantially cut seconds, as long as all son dp [a] row in descending order of the current point, successively determining two adjacent end points longest chain does not cross the path of the chain is the root node legal, if it legally can assign dp [i], otherwise, keep looking, and then cut the number plus one.

Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e6+10;
 4 struct node
 5 {
 6     int to;
 7     int next;
 8 }way[maxn];
 9 int head[maxn];
10 int tot=0;
11 int fa[maxn];
12 int top,sumn;
13 int x,y,s,n;
14 int a[maxn];
15 int add(int x,int y)
16 {
17     way[++tot].next=head[x];
18     way[tot].to=y;
19     head[x]=tot;
20 }
21 int dfs(int x,int f,int cut)
22 {
23     fa[x]=0;
24     for(int i=head[x];i;i=way[i].next)
25     {
26         if(way[i].to!=f)
27         {
28             dfs(way[i].to,x,cut);
29         }
30     }
31     top=0;
32     for(int i=head[x];i;i=way[i].next)
33     {
34         if(way[i].to!=f)
35         {
36             a[++top]=fa[way[i].to]+1;
37         }
38     }
39     sort(a+1,a+1+top);
40     while(top&&a[top]+a[top-1]>cut)
41     {
42         top--;
43         sumn++;
44     }
45     fa[x]=a[top];
46 }
47 int check(int x)
48 {
49     sumn=0;
50     dfs(1,0,x);
51     return sumn<=s;
52 }
53 int main()
54 {
55     cin>>n>>s;
56     for(int i=1;i<=n-1;i++)
57     {
58         cin>>x>>y;
59         add(x,y);
60         add(y,x);
61     }
62      
63     int l=0;
64     int r=n;
65     while(l<r)
66     {
67         int mid=(l+r)>>1;
68         if(check(mid))
69         {
70             r=mid;
71         }
72         else
73         {
74             l=mid+1;
75         }
76     }
77     cout<<l<<endl;
78     return 0;
79 }
 
  

 





Guess you like

Origin www.cnblogs.com/2529102757ab/p/11681390.html