Several methods diameter of the tree and evaluates all points most distant tree seek

A, dp (due to different definitions, there are two ways for writing, in fact dp too flexible wording is not surprising that there are several)

  One is recorded in each node (u) to the root, to a maximum distance of its sub-tree leaf node farthest (dp [u] [1]) and the second largest distance (dp [u] [0]); this in this subtree rooted at node is the diameter dp [u] [0] + dp [u] [1], that is, the diameter of the full tree for each node to take max;

void dfs(int u, int fa){for(int i = 0; i < G[u].size(); i++){
        int v = G[u][i].to, w = G[u][i].w;
        if (v == fa) continue;
        dfs(v, u);
        if (dp[u][1] < dp[v][1]+w){//维护最大和次大值
            dp[u][0] = dp[u][1];
            dp[u][1] = dp[v][1]+w;
        }
        else if (dp[u][0] < dp[v][1]+w)
            dp[u][0] = dp[v][1]+w;
    }
    ans = max(ans, dp[u][1]+dp[u][0]);
}

  

  Another recording only the maximum distance for node u, provided DP [u] in diameter subtree rooted at u, the dp [u] = max (dp [u], dp [u_son] + dist (u , u_son)); still take max is the diameter of the whole tree for each node;

void dfs(int u, int fa) {
    for(int i = 0; i < G[u].size(); i++){
        int v = G[u][i].to, w = G[u][i].w;
        if (v == fa) continue;
        dfs(v, u);
ans = max(ans, dp[u] + dp[v] + w);
dp[u] = max(dp[u], dp[v] + w);
  }
}

 

Second, twice dfs

  We direct this question to see how the aid hdu2196 dfs seek diameter, and trees all point to the farthest point from the tree. Just do dfs take a point, this point to find the root of the tree of the farthest leaf node, leaf nodes do this again after the dfs root, find his distance from the node and the farthest distance is the diameter of the tree . Proved slightly, the available reductio ad absurdum.

  This question said the following about the role of these three dfs.

  First: in an arbitrary node as a root, the fundamental goal is to find the diameter of a terminal a. In the process of recording the starting point for the distance to each node, but does not affect. If the node is the endpoint of the diameter, so good, if not, we will update later.

  Second: the first to find a root of this endpoint, DFS do it again, to find the other end B, to update all the nodes of a distance. (If the first node in the randomly selected is an endpoint, then twice dfs will be over, but we can not guarantee times and it happens)

  B is in the third dfs root node to update all the distance b. Since a node tree can be up to a maximum distance that it must be a large value to the distance of the diameter of the two end points, it ends the algorithm.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 
 6 const int inf=0x3f3f3f3f;
 7 const int maxn=1e4+50;
 8 struct edge{
 9     int to,w;
10     edge(int too,int ww):to(too),w(ww){}
11 };
12 vector<edge>G[maxn];
13 int dp[maxn],maxl,s;
14 
15 void dfs(int u,int f,int len){//len:起点到u的距离
16     if(maxl<len){
17         s=u;
18         maxl=len;
19     }
20     for(int i=0;i<G[u].size();i++){
21         int to=G[u][i].to, w=G[u][i].w;
22         if(f==to) continue;
23         dfs(to,u,len+w);
24         dp[to]=max(dp[to],len+w);
25     }
26 }
27 int main(){
28     ios::sync_with_stdio(0);
29     cin.tie(0); cout.tie(0);
30     int n;
31     while(cin>>n){
32         memset(dp,0,sizeof(dp));
33         for(int i=0;i<=n;i++) G[i].clear();
34         for(int i=2,to,w;i<=n;i++){
35             cin>>to>>w;
36             G[i].push_back(edge(to,w));
37             G[to].push_back(edge(i,w));
38         }
39         s=0; maxl=0;
40         dfs(1,0,0);
41         dfs(s,0,0);
42         dfs(s,0,0);
43         for(int i=1;i<=n;i++) cout<<dp[i]<<endl;
44     }
45     return 0;
46 }

 

  In addition there is a problem that dp wording, above said first dp bit like, a lot of the older generation of blog that is very detailed, not go into details.

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 
 6 const int inf=0x3f3f3f3f;
 7 const int maxn=1e4+50;
 8 struct Edge{
 9     int to,w;
10     Edge(int too,int ww){to=too,w=ww;}
11 };
12 vector<Edge>G[maxn];
13 int dp[3] [MAXN], ID [MAXN];
 14  // ID [u]: maximum distance when u u subtree, the first child node through which
 15  // DP [u] [0]: obtained in the longest distance u u all subtrees of
 16  // DP [u] [. 1]: u times long distance obtained in all subtrees of u
 . 17  // DP [u] [2]: by u the longest distance obtained father 
18 is  void DFS1 ( int U, int F) {
 . 19      for ( int I = 0 ; I <G [U] .size (); I ++) { // gET up 
20 is          int to G = [ U] [I] .to, W = G [U] [I] .W;
 21 is          IF (to == F) Continue ;
 22 is          DFS1 (to, U);
 23 is          IF (DP [0][u]<dp[0][to]+w){
24             dp[0][u]=dp[0][to]+w;
25             id[u]=to;
26         }
27     }
28     for(int i=0;i<G[u].size();i++){//get次长
29         int to=G[u][i].to,w=G[u][i].w;
30         if(to==f||id[u]==to) continue;
31         dp[1][u]=max(dp[1][u],dp[0][to]+w);
32     }
33 }
34 void dfs2(int u,int f){
35     for(int i=0;i<G[u].size();i++){
36         int to=G[u][i].to,w=G[u][i].w;
37         if(to==f) continue;
38         if(to==id[u])
39             dp[2][to]=max(dp[2][u],dp[1][u])+w;
40         else
41             dp[2][to]=max(dp[2][u],dp[0][u])+w;
42 
43         dfs2(to,u);
44     }
45 }
46 
47 int main(){
48     ios::sync_with_stdio(0);
49     cin.tie(0); cout.tie(0);
50     int n;
51     while(cin>>n){
52         memset(dp,0,sizeof(dp));
53         for(int i=0;i<=n;i++) G[i].clear();
54         for(int i=2,to,w;i<=n;i++){
55             cin>>to>>w;
56             G[i].push_back(Edge(to,w));
57             G[to].push_back(Edge(i,w));
58         }
59         dfs1(1,0);
60         dfs2(1,0);
61         for(int i=1;i<=n;i++)
62             cout<<max(dp[0][i],dp[2][i])<<endl;
63     }
 64      return  0 ;
65 }

 

Guess you like

Origin www.cnblogs.com/noobimp/p/11260235.html