zoukankan      html  css  js  c++  java
  • P4383-[八省联考2018]林克卡特树【wqs二分,树形dp】

    正题

    题目链接:https://www.luogu.com.cn/problem/P4383


    题目大意

    (n)个点的一棵树,要求删除(k)条边然后接上(k)条边权为(0)的边后形成的树上选择一对((p,q))(p)走简单路径到(q)的权值和最大。

    (n,kleq 3 imes 10^5)


    解题思路

    其实可以理解为选恰好(k+1)条不相交的路径(可以选择一个点)使得权值和最大,这样删除路径最顶部的那条边一定有方案构造。

    因为是恰好选择,所以考虑(wqs)二分,给每条路径加上一个权值(mid),然后考虑用树形(dp)做就很简单了。设(f_{i,0/1/2})表示(i)号点没有路径经过/在路径之间/作为路径顶部时子树内的最小权值,然后转移即可。

    时间复杂度:(O(nlog W))


    code

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const ll N=3e5+10;
    struct edge{
    	ll to,next,w;
    }a[N<<1];
    struct node{
    	ll w,g;
    }f[N][3];
    ll n,k,tot,c,ls[N];
    node operator+(node x,node y)
    {return (node){x.w+y.w,x.g+y.g};}
    node operator+(node x,ll y)
    {return (node){x.w+y,x.g};}
    node operator^(node x,ll y)
    {return (node){x.w,x.g+y};}
    node mx(node x,node y){
    	if(x.w==y.w)return (x.g>y.g)?x:y;
    	return (x.w>y.w)?x:y;
    }
    void addl(ll x,ll y,ll w){
    	a[++tot].to=y;
    	a[tot].next=ls[x];
    	a[tot].w=w;ls[x]=tot;
    	return;
    }
    void dfs(ll x,ll fa){
    	f[x][0]=f[x][1]=(node){0,0};f[x][2]=(node){c,1};
    	for(ll i=ls[x];i;i=a[i].next){
    		ll y=a[i].to;
    		if(y==fa)continue;dfs(y,x);
    		f[x][2]=mx(f[x][2]+f[y][0],(f[x][1]+f[y][1]+a[i].w+c)^1);
    		f[x][1]=mx(f[x][0]+f[y][1]+a[i].w,f[x][1]+f[y][0]);
    		f[x][0]=f[x][0]+f[y][0];
    	}
    	f[x][0]=mx(f[x][0],mx((f[x][1]+c)^1,f[x][2]));
    	return;
    }
    signed main()
    {
    	scanf("%lld%lld",&n,&k);
    	ll sum=0;k++;
    	for(ll i=1;i<n;i++){
    		ll x,y,w;
    		scanf("%lld%lld%lld",&x,&y,&w);
    		addl(x,y,w);addl(y,x,w);sum+=abs(w);
    	}
    	ll l=-sum,r=sum;
    	while(l<=r){
    		ll mid=(l+r)>>1;
    		c=mid;dfs(1,0);
    		if(f[1][0].g<k)l=mid+1;
    		else r=mid-1;
    	}
    	c=l;dfs(1,0);
    	printf("%lld
    ",f[1][0].w-c*k);
    	return 0;
    }
    
  • 相关阅读:
    mybatis
    队列
    JDK中的Timer和TimerTask详解
    NIOGoodDemo
    24-C#笔记-异常处理
    23-C#笔记-正则表达式
    22-C#笔记-预编译指令
    21-C#笔记-名称空间
    20-C#笔记-接口
    19-C#笔记-多态性
  • 原文地址:https://www.cnblogs.com/QuantAsk/p/15400445.html
Copyright © 2011-2022 走看看