HDU 2196 Computer (longest path of tree / diameter of tree)

Posted by nickdd on Wed, 08 Jan 2020 16:37:41 +0100

At the beginning of learning tree dp, people defined this problem as a simple problem. When I finished learning the other two branches of purple book, I looked back and found that I couldn't help it. I ran two kinds of dfs. On this network, the ideas were clearly written, but I couldn't understand the code. So I ran to find kuangbin's template. It's really good I see!

Idea: record the longest path and the second longest path from each tree to the subtree, in which the second longest path is obtained through the continuous replacement with the longest path (kuangbin wrote it really well here, learned it), and then record the longest path of the node whose father walked in reverse and didn't pass the longest path. Wow, it's easy to understand. Finally, compare it with the longest path To the optimal solution, we still need% kuangbin, as the standard

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<cmath>
using namespace std;
#define maxnn 10005
int maxn[maxnn];
int smaxn[maxnn];
int maxid[maxnn];
int smaxid[maxnn];
int head[maxnn];
int cnt;
struct node
{
    int to;
    int next;
    int w;
}e[maxnn * 2];
void addedge(int u, int v, int w)
{
    e[cnt].to = v;
    e[cnt].w = w;
    e[cnt].next = head[u];
    head[u] = cnt ++;
}
void init()
{
    cnt = 0;
    memset(head, -1, sizeof(head));
}
void dfs1(int u, int p)
{
    maxn[u] = smaxn[u] = 0;
    for(int i = head[u]; ~ i; i = e[i].next)
    {
        int v = e[i].to;
        if(v == p) continue;
        dfs1(v, u);
        if(smaxn[u] < maxn[v] + e[i].w)
        {
            smaxn[u] = maxn[v] + e[i].w;
            smaxid[u] = v;
            if(smaxn[u] > maxn[u])
            {
                swap(smaxn[u], maxn[u]);
                swap(smaxid[u], maxid[u]);
            }
        }
    }
}
void dfs2(int u, int p)
{
    for(int i = head[u]; ~ i; i = e[i].next)
    {
        int v = e[i].to;
        if(v == p) continue;
        if(v == maxid[u])
        {
            if(e[i].w + smaxn[u] > smaxn[v])
            {
                smaxn[v] = e[i].w + smaxn[u];
                smaxid[v] = u;
                if(smaxn[v] > maxn[v])
                {
                    swap(smaxn[v], maxn[v]);
                    swap(smaxid[v], maxid[v]);
                }
            }
        }
        else
        {
            if(e[i].w + maxn[u] > smaxn[v])
            {
                smaxn[v] = e[i].w + maxn[u];
                smaxid[v] = u;
                if(smaxn[v] > maxn[v])
                {
                    swap(smaxn[v], maxn[v]);
                    swap(smaxid[v], maxid[v]);
                }
            }
        }
        dfs2(v, u);
    }
}
int main()
{
    int n;
    while(scanf("%d",&n) != EOF)
    {
        init();
        int v, len;
        for(int i = 2; i <= n; i ++)
        {
            scanf("%d%d",&v,&len);
            addedge(i, v, len);
            addedge(v, i, len);
        }
        dfs1(1, -1);
        dfs2(1, -1);
        for(int i = 1; i <= n; i ++)
            printf("%d\n",maxn[i]);
    }
    return 0;
}

 

Topics: network