update
Why is CSDN so spicy?I poked it in and I'll publish it again?Then the time is not right.I wrote this earlier.
[Title]
LOJ
Given a tree with edge weights of nnn points, you can (and must) delete the KKK edges and connect the KKK edges with 1000 edges. The value is the right of large paths.Seek the greatest value you can get from all the solutions.
n,K≤3×105n,K\leq 3\times 10^5n,K≤3×105
[Solution ideas]
Considering that the edge has been deleted, what should the answer be in the tree?Apparently it is composed of chains in the original tree that happen to have K+1K+1K+1 points that do not intersect (a single point counts).
The problem now is to select the chain in the tree where the KKK points do not intersect to make the edge weights and maximizations.
Let fi,j,0/1/2f_{i,j,0/1/2}fi,j,0/1/2 represent the point in I I I where j j j chains are selected in the subtree, how many chains are connected in the point and subtree, and the maximum weight.Then the transfer is something like a backpack, complexity O(nk2)O(nk^2)O(nk2).
Observing that the function of the answer about KKK should be a unimodal function, consider weighted dichotomy.
Specifically, we divide the slope sss into two, and each time we select a new path, we need to lose the sss point weights, which requires the maximum weights and what they are.
This problem can be solved in O(n)O(n)O(n)O(n) time with a simple DP\text{DP}DP, just like before, with less KKK dimension.
This is O (n log_V) O(nlog V) O (n log V).
DP\text{DP}DP needs to record at least a few chains when it is optimal, but since the answer function may get the optimal value in a certain interval, it is impossible to exactly split the KKK chains, but that's OK, we can definitely construct an answer, so the answer that needs to be kept is the one closest to KK and no more than KK.
Some details: When dichotomizing, you only need to dichotomize within the integer range. When you select a single root node, it is considered to be connected to 111 chains in the subtree, updating in reverse order.
One warning: Do not overload the less than sign with the pair type, otherwise you are likely to have problems.(The code below is lazy to change, although it's correct to write it like that)
[Reference Code]
#include<bits/stdc++.h> #define fi first #define se second #define mkp make_pair using namespace std; typedef long long ll; typedef pair<int,ll>pii;//times,val const ll inf=1e15; const int N=3e5+10; int n,K,tot,head[N]; ll mid,ans,rem; pii f[N][3]; int read() { int ret=0,f=1;char c=getchar(); while(!isdigit(c)) {if(c=='-')f=0;c=getchar();} while(isdigit(c)) ret=ret*10+(c^48),c=getchar(); return f?ret:-ret; } struct Tway{int v,nex,w;}e[N<<1]; void add(int u,int v,int w) { e[++tot]=(Tway){v,head[u],w};head[u]=tot; e[++tot]=(Tway){u,head[v],w};head[v]=tot; } bool operator <(const pii&a,const pii&b){return a.se==b.se?a.fi>b.fi:a.se<b.se;} pii Max(const pii&a,const pii&b){return a<b?b:a;} pii operator +(const pii&a,const pii&b){return mkp(a.fi+b.fi,a.se+b.se);} pii operator +(const pii&a,const ll&b){return mkp(a.fi,a.se+b);} void gmax(pii&a,pii b,int c){b.fi+=c;a=Max(a,b);} void dfs(int x,int fa) { f[x][0]=mkp(0,0);f[x][1]=mkp(1,-mid);f[x][2]=mkp(0,-inf); for(int i=head[x];i;i=e[i].nex) { int v=e[i].v,w=e[i].w; if(v==fa) continue; dfs(v,x); pii a=Max(f[v][0],Max(f[v][1],f[v][2])); //printf("%d %lld\n",a.fi,a.se); gmax(f[x][2],f[x][2]+a,0);gmax(f[x][2],f[x][1]+f[v][1]+mid+w,-1); gmax(f[x][1],f[x][1]+a,0);gmax(f[x][1],f[x][0]+f[v][1]+w,0); gmax(f[x][0],f[x][0]+a,0); } } int solve() { dfs(1,0);pii res=mkp(0,-inf); for(int i=1;i<=n;++i) res=Max(res,Max(f[i][0],Max(f[i][1],f[i][2]))); if(res.fi<=K) ans=res.se; //printf("%lld %d %lld\n",mid,res.fi,res.se); return res.fi; } int main() { #ifndef ONLINE_JUDGE freopen("LOJ2478.in","r",stdin); freopen("LOJ2478.out","w",stdout); #endif n=read();K=read()+1; for(int i=1,x,y;i<n;++i) x=read(),y=read(),add(x,y,read()); ll l=-1e12,r=1e12; while(l<=r) { mid=(l+r)>>1; if(solve()<=K) rem=mid,r=mid-1; else l=mid+1; } printf("%lld\n",ans+rem*K); return 0; }