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. android webview无法加载网页

    主要原因是没有在AndroidManifest.xml里面设置如下: <user-permission android:name="android.permission.INTERNE ...

  2. Adjacent Bit Counts(动态规划 三维的)

    /** 题意: 给出一个01串 按照题目要求可以求出Fun(X)的值 比如: 111 Fun(111)的值是2: 输入: t (t组测试数据) n k (有n位01串 Fun()的值为K) 输出:有多 ...

  3. Java运行环境的配置(JDK和JRE)

    Jdk 表示java开发环境,包含开发环境和运行环境 Jre 表示java运行环境 JDK就是Java Development Kit.简单的说JDK是面向开发人员使用的SDK,它提供了Java的开发 ...

  4. TestNG关键字和testNG.xml结构学习

    转自官网:http://testng.org/doc/documentation-main.html#test-results TestNG关键字 @BeforeSuite@AfterSuite@Be ...

  5. 缓存管理Memorycache 的使用

      前言:什么是memoryCache? 一种缓存管理技术,某些只读数据频繁操作数据库,会对系统的性能有很大的开销,所以我们使用缓存技术,当数据库内容更新,我们在更更新缓存的数据值.目前缓存讲技术的产 ...

  6. java 类型转换:

    数值数据类型: 1.自动类型转换 byte->short ->int->long-->float--->double 范转小的类型向范围大的类型号转换,由系统自动完成   ...

  7. HttpClient4.0

    ****************************HttpClient4.0用法***************************** 1.初始化HttpParams,设置组件参数 //Ht ...

  8. winapi获取鼠标位置

    using System; using System.Drawing; using System.Runtime.InteropServices; using System.Threading; na ...

  9. Session深入理解

    Session是在什么情况下产生的 客户端访问服务器端,服务器端为每个用户生成一个唯一的sessionId,是这样吗?sessionId的作用是什么? http://www.cnblogs.com/s ...

  10. ICOMOON!强悍的WEB字体图标制造器/Web字体使用实例

    IcoMoon!一个可以通过个性化设置来创建自定义图标(字体)的生成器!也可以将SVG图片,转换成web字体 IcoMoon是一项免费的服务,通过使用不同设置使我们能够创建自定义的ICON图或ICON ...