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

HINT

 
考虑从1开始dfs,每次对于子树两个两个合并,多出来的往上合,第一问答案就是1+Σ(deg[x]-1)>>1
第二问答案显然具有可二分性,现在只需要判断答案x合不合法
对于每个点,把它子树所有点向上需要的答案统计出来到list[]中。
如果子树个数是偶数且这个点不是1号点,则额外加一个a[i]=0(因为有可能将一支向上连会更优,例子在后面)

然后对a排序,二分删掉a中的一个元素,从大到小匹配判断是否合法,如果任何方案都不合法,则是不合法的直接退出

如果弄到最后都合法,这个答案就合法,不过要注意判断根的时候如果子树是偶数个不能额外加元素,也不能二分判断,而要直接判断合法性

例子:

19
3 6
11 14
14 19
12 7
8 5
10 4
3 11
7 18
17 2
6 12
3 10
11 1
11 8
9 16
1 9
16 15

15 13

4 17

图:

code:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 10005
#define inf 1061109567
using namespace std;
char ch;
int n,a,b,tot,ans,now[maxn],son[maxn<<],pre[maxn<<],deg[maxn],cnt,up[maxn],list[maxn];
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b,deg[a]++;}
bool check(int x,int lim){
for (int i=,j=cnt;i<j;i++,j--){
if (i==x) i++; if (j==x) j--;
if (list[i]+list[j]>lim) return false;
}
return true;
}
bool dfs(int u,int fa,int lim){
for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if (v!=fa) if (!dfs(v,u,lim)) return false;
cnt=;
for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if (v!=fa) list[++cnt]=up[v]+;
if (!cnt) return true;
if (u!=&&!(cnt&)) list[++cnt]=;
sort(list+,list+cnt+);
if (u==&&!(cnt&)) return check(,lim);
int l=,r=cnt,m;
while (l!=r){
m=(l+r)>>;
if (check(m,lim)) r=m; else l=m+;
}
if (check(l,lim)) up[u]=list[l];
else up[u]=inf;
return up[u]<=lim;
}
int calc(){
int l=,r=n-,m;
while (l<r){
m=(l+r)>>;
if (dfs(,,m)) r=m;
else l=m+;
}
return l;
}
int main(){
while (~scanf("%d",&n)){
tot=;
memset(now,,sizeof(now));
memset(deg,,sizeof(deg));
memset(up,,sizeof(up));
for (int i=;i<n;i++) read(a),read(b),put(a,b),put(b,a);
ans=;
for (int i=;i<=n;i++) ans+=(deg[i]-)>>;
printf("%d %d\n",ans,calc());
}
return ;
}

bzoj2067: [Poi2004]SZN的更多相关文章

  1. 【BZOJ2067】[Poi2004]SZN 二分+树上贪心

    [BZOJ2067][Poi2004]SZN Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一 ...

  2. 【BZOJ2067】SZN(二分,动态规划,贪心)

    [BZOJ2067]SZN(二分,动态规划,贪心) 题面 权限题额 Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图 ...

  3. 【BZOJ2067】[Poi2004]SZN

    题解: 比上一题水多了 首先树上贪心,肯定要考虑儿子 然后我们会发现这个东西就是要先把儿子连起来 然后如果儿子个数为奇数我们可以把这一条和它连向父亲的并在一起 由于根没有父亲所以要单独考虑 答案就是s ...

  4. 2067: [Poi2004]SZN——树上贪心+二分

    题目大意: 给一棵树.求用最少的链覆盖这棵树(链不能相交),在这个基础上求最长的链最短可以是多少. n<=10000 题解: 肯定先处理第一问: 答案:$\sum_(du[i]-1)/2+1$ ...

  5. [POI2004] SZN

    Description 给定\(N(N\leq 10000)\)个点的树,要求用最少的路径覆盖树边.路径之间可以有交点,不能有交边.问最少需要几条路径以及在第一问的基础上最长的路径最短是多少? Sol ...

  6. bzoj 2067 [Poi2004]SZN——二分+贪心

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2067 最少的线段可以贪心地想出来.(结果还是写错了)就是偶数孩子可以自己配对,奇数孩子要带一 ...

  7. bzoj 2067: [Poi2004]SZN【贪心+二分+树形dp】

    第一问就是Σ(deg[u]-1)/2+1 第二问是二分,判断的时候考虑第一问的贪心规则,对于奇度数的点,两两配对之后一条延伸到上面:对于欧度数的点,两两配对或者deg[u]-2的点配对,然后一条断在这 ...

  8. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. svn server安装配置

    安装平台:RHEL5 1.安装软件:httpd.subversion.mod_dav_svn 2.修改配置 修改/etc/httpd/conf.d/subversion.conf.eg: LoadMo ...

  2. varnish esi出现no esi processing, first char not ‘<’的错误处理方式

    大致意思是varnish的ESI使用mod_deflate来处理可以接受含有请求头Accept-Encoding的请求,这样转发到后端服务器后,后端服务器返回的响应内容就不是一个格式良好的XML或ht ...

  3. FZU 2113 Jason的特殊爱好

    题意: 给定区间[a,b],求将区间中所有数写在黑板上,要写的数字‘1’的次数.(1 <= a,b <= 10^8) 解法: 将题转化成f(b+1) - f(a)的形式.普通的数位DP. ...

  4. Selenium webdriver 操作chrome 浏览器

    Step1: 下载chromedriver. 下载路径: http://chromedriver.storage.googleapis.com/index.html 选择一个合适的下载即可.我下载的是 ...

  5. Servlet的一些细节(2)

    1. Servlet的创建时间 Servlet是不能单独运行,调用它的叫做Servlet引擎,或者叫做web服务器 针对客户端的多长Servlet请求,通常情况下,服务器只会创建一个Servlet实例 ...

  6. servlet简介

    web 开发分为两种:静态开发(使用html)和动态开发(使用servlet/jsp,jsp就是servlet,ASP ,PHP) 所以servlet是sun公司提供的一门专门用于开发动态web资源的 ...

  7. 每一个web开发者都应该了解的HTTP/2

    我认为每一个 web 开发者都应该对这个支撑了整个 Web 世界的 HTTP 协议有所了解,这样才能帮助你更好的完成开发任务.在这篇文章中,我将讨论什么是 HTTP,它是怎么产生的,它的地位,以及我们 ...

  8. AE 3D摄像机工作原理

    看了AE教程的3D可视化音频和序列法导入三维模型之后对于视频解析3D是有了更深的认识.很感谢AE在CS6之后加入了3D摄像机跟踪器的功能.它是通过摄像机跟踪反求来得到影片中的平面特征点.然后由用户指定 ...

  9. Collections之sort、reverse

    在使用List集合时,通常情况下希望从集合中得到的对象是按照一定顺序排列的,但是List集合的默认排序方式为按照对象的插入顺序,可以通过java.util.Collections类的静态方法sort( ...

  10. Dump 文件生成与分析

    近期两天因为项目的须要,研究了一下Dump文件相关的知识,今天做一个小节(因为研究不久而且第一次写blog,希望网友们看到不要见笑). Dump文件是进程的内存镜像.能够把程序的运行状态通过调试器保存 ...