bzoj 4890: [Tjoi2017] urban tree dp

meaning of the title

Xiao Ming, who graduated from the University of garrison with a major in urban planning, came to work in a regional urban planning bureau. There are ri cities in this area. There are - 1 expressways, which ensure that any two transport cities can reach each other through expressways, but there is a certain traffic charge for passing through one expressway. Xiao Ming thought that the transportation cost in this area was too expensive after he studied it deeply. Xiaoming wants to completely transform this area, but due to the limited resources given to him by his superiors, he can only reconstruct one expressway now. The way of reconstruction is to remove one expressway and rebuild the same Expressway (i.e. the same transportation cost), so that the largest transportation cost between two cities in this area is the smallest (even if the transportation cost is the same The transportation cost between the largest two cities is the smallest), and any two cities can reach each other after construction. If you are Xiaoming, how can you solve this problem?
1<=n<=5000

Analysis

Simple tree dp.
Enumerating which side to delete, the maximum value must be one of the following two: the weighted diameter of two subtrees, or the longest path through the edge.
Then, dp is used to find the weighted diameter of two subtrees, and then dp is used to find the minimum value of the maximum value from each point to other points in the subtree for each subtree, and then removing the larger value is the optimal solution to delete this edge.

Code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

const int N=5005;
const int inf=1000000000;

int n,cnt,last[N],mn,val,mx1[N],mx2[N],bel1[N],bel2[N];
struct edge{int to,next,w;}e[N*2];

int read()
{
    int x=0,f=1;char ch=getchar();
    while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}

void addedge(int u,int v,int w)
{
    e[++cnt].to=v;e[cnt].w=w;e[cnt].next=last[u];last[u]=cnt;
    e[++cnt].to=u;e[cnt].w=w;e[cnt].next=last[v];last[v]=cnt;
}

void get_dia(int x,int fa)
{
    mx1[x]=mx2[x]=0;
    for (int i=last[x];i;i=e[i].next)
    {
        if (e[i].to==fa) continue;
        get_dia(e[i].to,x);
        if (mx1[e[i].to]+e[i].w>mx1[x]) mx2[x]=mx1[x],mx1[x]=mx1[e[i].to]+e[i].w;
        else if (mx1[e[i].to]+e[i].w>mx2[x]) mx2[x]=mx1[e[i].to]+e[i].w;
    }
    val=max(val,mx1[x]+mx2[x]);
}

void get_cen1(int x,int fa)
{
    mx1[x]=mx2[x]=0;
    for (int i=last[x];i;i=e[i].next)
    {
        if (e[i].to==fa) continue;
        get_cen1(e[i].to,x);
        int v=mx1[e[i].to]+e[i].w,id=e[i].to;
        if (v>mx1[x]) mx2[x]=mx1[x],bel2[x]=bel1[x],mx1[x]=v,bel1[x]=id;
        else if (v>mx2[x]) mx2[x]=v,bel2[x]=id;
    }
}

void get_cen2(int x,int fa)
{
    mn=min(mn,mx1[x]);
    for (int i=last[x];i;i=e[i].next)
    {
        if (e[i].to==fa) continue;
        int v,to=e[i].to;
        if (bel1[x]==e[i].to) v=mx2[x]+e[i].w;
        else v=mx1[x]+e[i].w;
        if (v>mx1[to]) mx2[to]=mx1[to],bel2[to]=bel1[to],mx1[to]=v,bel1[to]=x;
        else if (v>mx2[to]) mx2[to]=v,bel2[to]=x;
        get_cen2(e[i].to,x);
    }
}

int main()
{
    n=read();
    for (int i=1;i<n;i++)
    {
        int x=read(),y=read(),z=read();
        addedge(x,y,z);
    }
    int ans=inf;
    for (int i=1;i<n;i++)
    {
        int x=e[i*2-1].to,y=e[i*2].to,z=e[i*2].w;
        val=0;get_dia(x,y);get_dia(y,x);
        mn=inf;get_cen1(x,y);get_cen2(x,y);
        int tmp=mn;
        mn=inf;get_cen1(y,x);get_cen2(y,x);
        val=max(val,tmp+mn+z);
        ans=min(ans,val);
    }
    printf("%d",ans);
    return 0;
}

Posted by kritikia on Mon, 04 May 2020 13:06:30 -0700