CF1917F:Construct Tree 题解

F:

题意:给你所有边的边权,问你能不能组成直径为d的一棵树。n,d<=2000。

Solution:

可以看出是个背包,然后不在直径上的那些边怎么安置呢。可以分成三种情况:

  1. 最长边加次长边大于d,直接No。
  2. 除去第一种情况下,如果直径包含最长边,那么未选入直径的边都可以接在最长边旁边,一定合法,做普通背包可求得。
  3. 不选最长边,这时最长边一定会接在中间的某个位置,需要满足这个位置两边都比它长。

可以看出这是个双背包问题,dp[i][j] 表示是否可以做到左边集合长 i ,右边集合长 j 。每次加入一条新边分为放入左边集合和放入右边集合,转移方式都非常简单。

省空间需要压缩掉枚举第几条边,然后注意倒着转移。压缩时间则是用bitset,因为不需要记录方案数,只需要记录是否可行。

这个dp矩阵的两维是对称的,开d个bitset,倒着枚举第一维,每次先横向转移,再纵向转移,就搞定了空间上的压缩:

bitset <N> b[N]; b[0][0] = 1; for(int i=1;i<=n;i++) { for(int j=d;j>=0;j--) { b[j] |= (b[j]<<a[i]); if(j>=a[i]) b[j] |= b[j-a[i]]; } }

虽然是有史以来写的最烂的一次题解,不过既然你都做到这题了,这点东西你肯定一看就懂。qwq

my submission


__EOF__

本文作者枫叶晴
本文链接https://www.cnblogs.com/maple276/p/17985480.html
关于博主:菜菜菜
版权声明:呃呃呃
声援博主:呐呐呐
posted @   maple276  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示