博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Jzoj5455【NOIP2017提高A组冲刺11.6】拆网线
阅读量:5166 次
发布时间:2019-06-13

本文共 1084 字,大约阅读时间需要 3 分钟。

企鹅国的网吧们之间由网线互相连接,形成一棵树的结构。现在由于冬天到了,供暖部门缺少燃料,于是他们决定去拆一些网线来做燃料。但是现在有K只企鹅要上网和别人联机游戏,所以他们需要把这K只企鹅安排到不同的机房(两只企鹅在同一个机房会吵架),然后拆掉一些网线,但是需要保证每只企鹅至少还能通过留下来的网线和至少另一只企鹅联机游戏。

所以他们想知道,最少需要保留多少根网线?

今天考场上又zz了,只切了第二题qwq

第一题打了一个很显然不对的贪心,35pts   QwQ

后来一交流发现:树上二分图匹配啊!

怎么明明想到了要尽量多选没有公共端点的边但是没有想到匹配啊(这样下去我可能今年就要退役了)

好了正题开始

上面已经说出正解了,但是很显然我们不能真的去跑匈牙利

设f[i][0]表示在x的子树中,x没有被选择的情况下最多有多少对点是两两配对的

f[i][1]表示x被选择的情况,显然f[i][0]=Σf[v][1] ,f[i][1]=max{f[i][0]-f[v][1]+f[v][0]+2} {v∈son[i]}

让后,我们令ans=max(f[1][0],f[1][1])

若2ans>=k 那么答案就是(k+1)/2

否则就是ans+(k-2ans)(显然没有两两配对的点,可以通过加一条边来增加一个点(一换一)

#include
#include
#include
#include
using namespace std;int n,k,f[100010][2],ans=0; vector
G[100010];void dp(int x,int p){ f[x][0]=f[x][1]=0; for(int v,i=0,z=G[x].size();i
=k) printf("%d\n",k+1>>1); else printf("%d\n",ans+(k-ans*2));}int main(){ freopen("tree.in","r",stdin); freopen("tree.out","w",stdout); int T; for(scanf("%d",&T);T--;vvv());}

转载于:https://www.cnblogs.com/Extended-Ash/p/7800607.html

你可能感兴趣的文章
Web前端:如何实现选择select下拉框选中跳转其他页面
查看>>
制作自动化系统安装U盘
查看>>
Tost元素识别
查看>>
spotlight on mysql 监控
查看>>
jmeter目录讲解
查看>>
中国电信猫后接路由器具体设置
查看>>
机器学习中的正则化
查看>>
JavaScript -- Table
查看>>
跨浏览器的事件处理程序
查看>>
document.write
查看>>
ASP.Net
查看>>
[Java]读取文件方法(转)
查看>>
React 从入门到进阶之路(六)
查看>>
ACM牛人博客
查看>>
二分搜索 Codeforces Round #218 (Div. 2) C. Hamburgers
查看>>
Codeforces Round #336 (Div. 2)
查看>>
gunicorn运行显示connection in use解决办法
查看>>
CSUST 1506 ZZ的计算器 模拟题
查看>>
2013“嘉杰信息”杯ACM/ICPC湘潭多省程序设计竞赛暨湘潭市第五届大学生程序设计竞赛 F题 five tiger 湘潭大学1173题...
查看>>
20个国外创意404错误页面设计
查看>>