ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解-八省联考2018 林克卡特树

2021-07-22 19:01:28  阅读:183  来源: 互联网

标签:八省 ch 题解 maxn mp fi pi 联考 define


我们先来转换一下题意,即为选 \(k+1\) 条互不相交的链,使得权值和最大。估计没人和我一样选 \(k\) 条小于 \(0\) 的边变成 \(0\) 吧

这个东西看起来就只能 dp 求,设 f[i,j,0/1/2] 代表以 i 为根的子树选出 j 条链,然后 i 不选,i 是一条链的顶,i 的子树中有一条穿过 i 的链。

然后转移就比较显然了,为了方便,我们最后合并信息到 \(f[i,j,0]\) 上。通过打表我们发现这是一个关于 j 的凸函数,所以可以 wqs 二分。根据数据范围也可以猜测。我们稍微改写一下 dp 方程即可。

然后我的写法又丑又难写还难调,于是我打开了题解,看到了下面这种写法,稍微学习了一下(就是用一个 pair 来存,然后重载运算符)。

#include<bits/stdc++.h>
#define pi pair<ll,int>
#define mp make_pair
#define fi first
#define se second
typedef long long ll;
using namespace std;
const int maxn=600005;
const ll inf=0x3f3f3f3f3f3f3f3f;
template<typename T>
void read(T &x){
	T flag=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar())if(ch=='-')flag=-1;
	for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
	x*=flag;
}
int n,m;
int pre[maxn],to[maxn],val[maxn],head[maxn],tot=1;
pi f[maxn][3],I;
pi operator+(pi a,pi b){
	return mp(a.fi+b.fi,a.se+b.se);
}
pi operator+(pi a,ll b){
	return mp(a.fi+b,a.se);
}
bool operator<(pi a,pi b){
	if(a.fi!=b.fi)return a.fi<b.fi;
	return a.se<b.se;
}
void add_edge(int u,int v,int w){
	pre[++tot]=head[u];to[tot]=v;val[tot]=w;head[u]=tot;
}
void dfs(int u,int fa){
	f[u][0]=f[u][1]=f[u][2]=mp(0,0);
	f[u][2]=max(f[u][2],I);
	for(int i=head[u];i;i=pre[i]){
		int v=to[i];
		if(v==fa)continue;
		dfs(v,u);
		f[u][2]=max(f[u][2],max(f[u][2]+f[v][0],f[u][1]+f[v][1]+I+val[i]));
		f[u][1]=max(f[u][1],max(f[u][0]+f[v][1]+val[i],f[u][1]+f[v][0]));
		f[u][0]=max(f[u][0],f[u][0]+f[v][0]);
	}
	f[u][0]=max(f[u][0],max(f[u][1]+I,f[u][2]));
}
int main(){
	read(n);read(m);m++;
	for(int i=1,u,v,w;i<n;i++){
		read(u);read(v);read(w);
		add_edge(u,v,w);add_edge(v,u,w);
	}
	ll l=-1e12,r=1e12,res=0;
	while(l<=r){
		ll mid=(l+r)/2;
		I=mp(-mid,1);
		dfs(1,0);
		int v=f[1][0].se;
		if(v>=m){
			res=mid;
			l=mid+1;
		}else{
			r=mid-1;
		}
	}
	I=mp(-res,1);
	dfs(1,0);
	printf("%lld\n",f[1][0].fi+res*m);
	return 0;
}

标签:八省,ch,题解,maxn,mp,fi,pi,联考,define
来源: https://www.cnblogs.com/zcr-blog/p/15045699.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有