HDU 2196 Computer

Question meaning: Given n points, it is guaranteed to be a tree, and output the maximum distance from each point to other points.

First, the topic is DP thinking.

So let's first think that for a point, there are two cases for the point with the largest distance from it, one is in its subtree, and the other is through its parent node.

So we assume that dp[ i ][ 0 ] represents the maximum distance from a point to a point on its subtree, and dp[ i ] [ 1 ] represents the second largest distance (we will talk about the use of the second largest distance later).

So one situation is solved, so how to solve the situation from the parent node?

We first set dp[ i ] [ 2 ] to be the longest path from the parent node of i .

We can think of recursing from the parent node to the child node. If a point is farthest from its parent node, then the store is also the farthest point of its parent node relative to its parent node, which works.

But the farthest point of the parent node has two situations, one is that the farthest path contains the child node, or it does not contain the child node.

The first case: For the included case, we cannot go this way, we must use the second largest distance mentioned above, that is to say, assuming that h is the parent node of i,

Then dp[i][2] in this case is equal to the maximum distance of the parent node (point h) + the distance of point h to point i, and the maximum distance of the parent node is to be between dp[h][1] and dp[ h ] [ 2 ],

Because relative to a certain point, we only find the maximum in the subtree and the maximum through its parent node to the node, and taking a maximum value between the two is the final maximum value.

In this case, the second largest value is not the largest value, so choose dp[ h ][ 1 ] instead of dp[ h ][ 2 ]. (If you don't understand these two lines, you can look at the second case below)

That is, dp[ i ][ 2 ] =max( dp[ h ][ 1 ] ,dp[ h ] [ 2 ] ) + the value of h to i.

The second case: if not included, then we directly take the maximum path of the parent node plus the path from the parent node to the node.

As mentioned above, the maximum path to its parent node should take the maximum value of dp[ h ][ 0 ] and dp[ h ][ 2 ], that is, the maximum path from the parent node of the parent node and the maximum path on the subtree of the parent node. Choose the largest of the two.

So dp[ i ][ 2 ] = max( dp[ h ][ 0] ,dp[ h ] [ 2 ] ) + the value of h to i.

The method of judging whether the maximum road of the parent node passes through this road does not require additional records, only need to judge

dp[ i ][ 0 ] + h to i can be equal to dp[ h ] [ 0 ].

code show as below:

#include <iostream>  
#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#include <cmath>  
#include <queue>  
#include <vector>  
#include <map>  
#include <set>  
#include <string>  
using namespace std;      
  
struct node
{  
    int to;  
    int val;  
};  
vector<node> q[10005];  
int dp[10005][4],n;
 
void dfs1(int root)  
{  
    int most=0,second=0;  
    for(int i=0;i<q[root].size();i++)  
    {  
        node child=q[root][i];  
        dfs1(child.to);  
        int cost=dp[child.to][0]+child.val;  
        if(cost>=most)  
        {  
            second=most;  
            most=cost;  
        }  
        else if(cost>second)  
            second = cost;  
    }  
    dp[root][0]=most;  
    dp[root][1]=second;  
}  

void dfs2(int root)  
{  
    for(int i=0;i<q[root].size();i++)  
    {  
        node child=q[root][i];  
        if(dp[child.to][0]+child.val==dp[root][0])
            dp[child.to][2]=max(dp[root][2],dp[root][1])+child.val;  
        else
            dp[child.to][2]=max(dp[root][2],dp[root][0])+child.val;
        dfs2(child.to);  
    }  
}  
intmain ()  
{  
    while(~scanf("%d",&n))  
    {  
        for(int i=2;i<=n;i++)  
        {  
            int x,y;  
            scanf("%d%d",&x,&y);  
            node a;a.val = y;  
            a.to=i;  
            q[x].push_back(a);  
        }  
        memset(dp,0,sizeof dp);  
        dfs1 ( 1 );  
        dp[1][2]=0;  
        dfs2(1);  
        for(int i=1;i<=n;i++)  
            printf("%d\n",max(dp[i][0],dp[i][2]));  
        for(int i=1;i<=n;i++)  
            q[i].clear();  
    }  
    return 0;  
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325017551&siteId=291194637