JZOJ 5496. [Tsinghua Training 2017 Simulation 12.09] Tree

subject


Data Range

Problem

In one of the previous questions, you can draw a conclusion that some of the conditions of the division will certainly be helpful in solving the problem.
Let's look at k=n first.Apparently the sum of edges*2-diameter.
Generally, when state transition is made, it is carried out according to the condition "sum of edges*2-diameter".
So there are so many points.
First, when transferring, it must be guaranteed that the transferred state is optimal, so how can the sum of edges 2-diameter be guaranteed to be the smallest when transferring?First, this state must store the minimum value of 2-diameter of the current sum of edges, and then the state after the transfer must store the minimum value of 2-diameter of the current sum of edges.
Next, it is discussed whether both ends of the diameter are on X (the point of current transfer).
To sum up, set up
g[x,i] denotes that the subtree of X selects the minimum value of the edge of the tree that consists of the I points that are connected.
f0[x,i] indicates that the subtree of X selects I points, and the edge*2-the minimum diameter of the tree formed by one end of the diameter on X.
f1[x,i] indicates that the subtree of X has selected I points, and the edge*2-the minimum diameter of the tree formed by not having one end of the diameter on X.
So how do you keep all the facts intact?As you work through point x, your son's subtrees discuss merging one by one.This is the classic way of doing a tree backpack.
Clearly, there are three scenarios to discuss for transfer.
1. Diameter in a new subtree.(2) The diameter is in the treated part.
(3) The diameter of (u,v) can update the answer (for updating f1).
For updates to f0, update with F0 + g*2 for parts with diameter and parts without diameter.
The 1 and 2 of f1 are similar to that of f0.Third, it's very simple.

summary

One of the most important points is that when you operate on point x, your son's subtrees are discussed one by one, and the merger is completed.
(2) For cases where the shortest path is difficult to be represented by a one-time transfer, the optimal transfer can be guaranteed each time.

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 3010
#define Inf 1061109567
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
struct note{
    int to,next,val;
};note edge[N*2];
int tot,head[N],fa[N],siz[N],ans;
int i,K,n,u,v,z,temp,t1,t2;
int g[N][N],f0[N][N],f1[N][N]; 
void lb(int x,int y,int z){edge[++tot].to=y;edge[tot].next=head[x];edge[tot].val=z;head[x]=tot;}
void mi(int &x,int y){x=x<y?x:y;}
void dg(int x){
    int i,j,k;
    siz[x]=1;f0[x][1]=g[x][1]=0;
    for(i=head[x];i;i=edge[i].next){
        if(fa[x]==edge[i].to)continue;
        fa[edge[i].to]=x;
        dg(edge[i].to);
    }
    for(i=head[x];i;i=edge[i].next){
        if(fa[x]==edge[i].to)continue;
        t1=siz[x]<K?siz[x]:K;
        t2=siz[edge[i].to]<K?siz[edge[i].to]:K;
        fd(j,t1,1)
            fd(k,t2,1)
            if(j+k<=K){
                temp=edge[i].val;
                mi(g[x][j+k],g[x][j]+g[edge[i].to][k]+temp);
                mi(f0[x][j+k],f0[x][j]+2*(g[edge[i].to][k]+temp));
                mi(f0[x][j+k],f0[edge[i].to][k]+2*g[x][j]+temp);
                mi(f1[x][j+k],f1[x][j]+2*(g[edge[i].to][k]+temp));
                mi(f1[x][j+k],f1[edge[i].to][k]+2*(g[x][j]+temp));
                mi(f1[x][j+k],f0[x][j]+f0[edge[i].to][k]+temp);
            }
        siz[x]+=siz[edge[i].to];
    }
}
int main(){
    scanf("%d%d",&n,&K);
    fo(i,1,n-1){
        scanf("%d%d%d",&u,&v,&z);
        lb(u,v,z);lb(v,u,z);
    }
    memset(g,63,sizeof(g));
    memset(f0,63,sizeof(f0));
    memset(f1,63,sizeof(f1));
    dg(1);
    ans=Inf;
    fo(i,1,n)mi(ans,f0[i][K]),mi(ans,f1[i][K]); 
    printf("%d",ans);
    return 0;
}

Posted on Sat, 30 May 2020 12:50:39 -0400 by hach22