【BZOJ2067】SZN(二分,动态规划,贪心)
【BZOJ2067】SZN(二分,动态规划,贪心)
题面
Description
String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一些顶点和特定数量的边构成. 每个顶点都可以连向许多的其他顶点.一个图是连通且无环的. 图是由许多的线做成的.一条线是一条连接图中两个顶点之间的路径.由于一些技术原因,两条线之间不能有重叠的部分,要保证图中任意一条边都被且仅被一条线所覆盖.由于一些技术原因,做一个这样的图的模型的费用取决于用了多少条线以及最长的那条的长度. (每条边的长度都为1.),给出对应的图,求出最少能用多少条线以及在用最少线的情况下最长的那根线最短可以为多少.
Input
第一行仅包含一个数n – 顶点的总数, 2 <= n <= 10 000. 顶点从1 到 n进行编号. 接下来的n - 1 行描述这些边, 每行两个数a 和 b, 1 <= a, b <= n, a <> b. 表示顶点a和顶点b之间有一条边.
Output
输出两个数,最少用多少条线以及在用最少线的情况下最长线最短可以为多少.
Sample Input
9
7 8
4 5
5 6
1 2
3 2
9 8
2 5
5 8
Sample Output
4 2
题解
首先第一问答案是\(1+\sum (d_i-1)/2\),其中\(d_i\)是\(i\)的度数。这个东西你可以认为是每个节点的所有儿子两两配对,而多出来的部分则可以延伸到父亲上面去继续做。
那么只需要考虑第二问。我们二分一个答案,设\(f[i]\)表示可以向上延伸的最小长度,那么每次对于一个点,把它的所有儿子拿出来排个序,看看延伸上去的最少长度是多少。
当然,这里要分奇偶性来看。如果一个点的儿子数是奇数,那么我们排序之后二分最小的那个延伸上去的儿子。如果是偶数,我们先尝试两两配对,如果不合法那么再考虑一下前面的式子,允许有一个儿子可以延伸到父亲去,而偶数的贡献则只需要匹配儿子数/2-1对,所以可以直接把最大值去掉再当成奇数尝试匹配。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 10010
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1,dg[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int n,ans=1,f[MAX],mid;
int S[MAX],top,vis[MAX];bool fl;
void dfs(int u,int ff)
{
if(!fl)return;
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=ff)dfs(e[i].v,u);
top=f[u]=0;
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=ff)S[++top]=f[e[i].v]+1;
sort(&S[1],&S[top+1]);
if(!top)return;
if(S[top]>mid){fl=false;return;}
if(top%2==0)
{
for(int i=1;i<=top/2;++i)
if(S[i]+S[top-i+1]>mid)
{
if(u!=1){--top;break;}
fl=false;return;
}
}
if(top%2==1)
{
int l=1,r=top,ret=top+1;
while(l<=r)
{
int Mid=(l+r)>>1;bool chk=true;
for(int i=1,j=top;;++i,--j)
{
if(i==Mid)++i;if(j==Mid)--j;
if(i>=j)break;
if(S[i]+S[j]>mid){chk=false;break;}
}
if(chk)ret=Mid,r=Mid-1;
else l=Mid+1;
}
if(ret>top){fl=false;return;}
else f[u]=S[ret];
}
}
int main()
{
n=read();
for(int i=1;i<n;++i)
{
int u=read(),v=read();
Add(u,v);Add(v,u);
dg[u]++;dg[v]++;
}
for(int i=1;i<=n;++i)ans+=(dg[i]-1)/2;
int l=1,r=n,ret=1;
while(l<=r)
{
mid=(l+r)>>1;fl=true;
dfs(1,0);memset(vis,0,sizeof(vis));
if(fl)ret=mid,r=mid-1;
else l=mid+1;
}
printf("%d %d\n",ans,ret);
return 0;
}
【BZOJ2067】SZN(二分,动态规划,贪心)的更多相关文章
- 【BZOJ2067】[Poi2004]SZN 二分+树上贪心
[BZOJ2067][Poi2004]SZN Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一 ...
- $bzoj2067\ szn$ 二分+贪心
正解:二分+贪心 解题报告: 传送门$QwQ$ 题目大意就说有一棵树,然后要用若干条线覆盖所有边且不能重叠.问最少要用几条线,在用线最少的前提下最长的线最短是多长. 昂首先最少用多少条线这个还是蛮$e ...
- CodeForces - 363D --二分和贪心
题目:CodeForces - 363D 题意:给定n个学生,其中每个学生都有各自的私己钱,并且自己的私己钱只能用在自己买自行车,不能给别人. 给定m个自行车,每个自行车都有一个价格. 给定公有财产a ...
- 【BZOJ1816】[CQOI2010]扑克牌(二分,贪心)
[BZOJ1816][CQOI2010]扑克牌(二分,贪心) 题面 BZOJ 题解 看了一眼这题,怎么这么眼熟?woc,原来\(xzy\)的题目是搬的这道啊... 行,反正我考的时候也切了,这数据范围 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- hdu 4004 (二分加贪心) 青蛙过河
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4004 题目意思是青蛙要过河,现在给你河的宽度,河中石头的个数(青蛙要从石头上跳过河,这些石头都是在垂 ...
- BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心
BZOJ_2196_[Usaco2011 Mar]Brownie Slicing_二分答案+贪心 Description Bessie烘焙了一块巧克力蛋糕.这块蛋糕是由R*C(1 <= R,C ...
- 洛谷3933 Chtholly Nota Seniorious 二分答案+贪心
题目链接 题意 给你一个N*M的矩阵 (N,M <=2000) 把他分成两部分 使两部分的极差较大的一个最小 求这个最小值.然后分矩阵的要求是:每个部分内部的方块之间,可以通过上下左右相互到 ...
- BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)
dp容易想到,但没法进一步优化了. 考虑贪心,每次选出价值最大的物品.但这显然是不对的因为会影响其他物品的选择. 于是考虑加上反悔操作.每次选出一个物品后,将其相邻两物品删除,再将原物品价值变为相邻两 ...
- bzoj 2067 [Poi2004]SZN——二分+贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2067 最少的线段可以贪心地想出来.(结果还是写错了)就是偶数孩子可以自己配对,奇数孩子要带一 ...
随机推荐
- 剖析管理所有大数据组件的可视化利器:Hue
日常的大数据使用都是在服务器命令行中进行的,可视化功能仅仅依靠各个组件自带的web界面来实现,不同组件对应不同的端口号,如:HDFS(50070),Yarn(8088),Hbase(16010)等等, ...
- Elasticsearch 简介
1. 背景 Elasticsearch 在公司的使用越来越广,很多同事之前并没有接触过 Elasticsearch,所以,最近在公司准备了一次关于 Elasticsearch 的分享,整理成此文.此文 ...
- Delphi DBGrid类控件定位到某一行,并更改为选中状态。
Delphi中,可以使用数据集控件提供的 Locate 成员方法快速定位至某条记录, 然后通过清除数据集控件的选中状态,并重新赋值达到我们的目的. grDirectory.DataSource.Dat ...
- Java基础—异常
一.概念 异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 异常体 Throwable:所有异常类的超类 Error:它表示不希望被程序捕获或者是程序无法处理的错误 ...
- Android应用安全之数据传输安全
Android软件通常使用WIFI网络与服务器进行通信.WiFi并非总是可靠的,例如,开放式网络或弱加密网络中,接入者可以监听网络流量:攻击者可能 自己设置WIFI网络钓鱼.此外,在获得root权限后 ...
- 20155327 EXP8 Web基础
20155320 EXP8 Web基础 基础问题回答 什么是表单? 表单:可以收集用户的信息和反馈意见,是网站管理者与浏览者之间沟通的桥梁. 表单由文本域.复选框.单选框.菜单.文件地址域.按钮等表单 ...
- 如何查看哪个进程,使用了哪个CPU
某些时候,我们需要知道,在Unix/Linux 环境中,CPU究竟消耗在了哪些进程上面. 如下是最简单的方法: ps -elF
- pygame 入门实例
本文基于win7(64) + py3.5(64)环境. 本文是这里的一篇学习笔记.加入了自己的理解. 本文最终目的是实现一个飞机躲避导弹的游戏. 1.核心概念 pygame 的核心概念有: Surfa ...
- effective c++ 笔记 (31-34)
//---------------------------15/04/20---------------------------- //#32 确定你的public继承塑膜出 is-a 关系 { ...
- 浅谈 iOS 中的 Activity Indicator
Activity Indicator 是iOS开发中必不可少的一个视图.本文就简单地总结一下这个Activity Indicator 的使用方法. 默认 Activity Indicator 以下的函 ...