【BZOJ2067】[Poi2004]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

HINT

题解:第一问结论好重要啊。

设一个点的度数为d[i],我们统计多少条路径的最高点是这个点。对于非根的点,它肯定有一条路是从父亲那里来的,这条路还能延伸至它的一个儿子。那么对于剩下的儿子,将他们两两配对,剩余的单算,所以这个点对答案的贡献就是$\lceil\frac {d[i]-2} 2\rceil = \lfloor \frac {d[i]-1} 2 \rfloor$。对于根节点,它的贡献是$\lceil\frac {d[1]} 2\rceil$,所以$ans=1+\sum\limits_{i=1}^n\lfloor \frac {d[i]-1} 2 \rfloor$。

第二问的思路与第一问类似,容易想到先二分答案limit,然后令f[i]表示i到父亲那条路径的最短长度是多少。那么f[i]怎么求呢?我们将i的所有儿子的f值拿出来排序,发现i的f值可以二分得到。假如f[i]=f[j]+1,那么我们将j去掉,其余的f值从不断取出最大的和最小的两两配对,如果所有配对后的路径长度都<=limit,则这是一个合法的f值,继续二分即可。

注意:如果一个点的儿子个数是奇数,那么我们需要再添一个f值为0的儿子。根节点的f值需要特殊处理。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. using namespace std;
  5. const int maxn=10010;
  6. int n,m,ans,cnt,lim,flag;
  7. int to[maxn<<1],next[maxn<<1],head[maxn],d[maxn];
  8. int g[maxn],f[maxn];
  9. inline void add(int a,int b)
  10. {
  11. to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
  12. }
  13. bool check(int x)
  14. {
  15. int i,j;
  16. for(i=1,j=m;i<j;i++,j--)
  17. {
  18. if(i==x) i++;
  19. if(j==x) j--;
  20. if(g[i]+g[j]>lim) return 0;
  21. }
  22. return 1;
  23. }
  24. void dfs(int x,int fa)
  25. {
  26. int i;
  27. for(i=head[x];i!=-1;i=next[i]) if(to[i]!=fa) dfs(to[i],x);
  28. for(m=0,i=head[x];i!=-1;i=next[i]) if(to[i]!=fa) g[++m]=f[to[i]]+1;
  29. if(x==1)
  30. {
  31. sort(g+1,g+m+1);
  32. flag&=check((m&1)?m:0);
  33. return ;
  34. }
  35. if(!(m&1)) g[++m]=0;
  36. sort(g+1,g+m+1);
  37. int l=1,r=m+1,mid;
  38. while(l<r)
  39. {
  40. mid=(l+r)>>1;
  41. if(g[mid]+1<=lim&&check(mid)) r=mid;
  42. else l=mid+1;
  43. }
  44. if(r==m+1) flag=0;
  45. f[x]=g[r];
  46. }
  47. inline int rd()
  48. {
  49. int ret=0,f=1; char gc=getchar();
  50. while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
  51. while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
  52. return ret*f;
  53. }
  54. int main()
  55. {
  56. n=rd();
  57. int i,a,b,l=1,r=n;
  58. memset(head,-1,sizeof(head));
  59. for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a),d[a]++,d[b]++;
  60. for(ans=i=1;i<=n;i++) ans+=(d[i]-1)>>1;
  61. while(l<r)
  62. {
  63. flag=1,lim=(l+r)>>1,dfs(1,0);
  64. if(flag) r=lim;
  65. else l=lim+1;
  66. }
  67. printf("%d %d",ans,r);
  68. return 0;
  69. }

【BZOJ2067】[Poi2004]SZN 二分+树上贪心的更多相关文章

  1. bzoj 2525: [Poi2011]Dynamite【二分+树上贪心】

    一眼二分.然后重点是树上贪心部分 长得像dp一样,设mn为子树内已炸点的最浅点,mx为子树内没有炸并且需要炸的最深点,然后转移直接从子树继承即可 然后是判断当前u点是否需要炸,当mx[u]+mn[u] ...

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

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

  3. bzoj2067: [Poi2004]SZN

    Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一些顶点和特定数量的边构成. 每个顶点都可以连向 ...

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

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

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

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

  6. 【BZOJ2067】[Poi2004]SZN

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

  7. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  8. CodeForces - 363D --二分和贪心

    题目:CodeForces - 363D 题意:给定n个学生,其中每个学生都有各自的私己钱,并且自己的私己钱只能用在自己买自行车,不能给别人. 给定m个自行车,每个自行车都有一个价格. 给定公有财产a ...

  9. 【BZOJ1816】[CQOI2010]扑克牌(二分,贪心)

    [BZOJ1816][CQOI2010]扑克牌(二分,贪心) 题面 BZOJ 题解 看了一眼这题,怎么这么眼熟?woc,原来\(xzy\)的题目是搬的这道啊... 行,反正我考的时候也切了,这数据范围 ...

随机推荐

  1. POJ 2750 Potted Flower (单点改动求线段树上最大子序列和)

    题目大意: 在一个序列上每次改动一个值,然后求出它的最大的子序列和. 思路分析: 首先我们不考虑不成环的问题.那就是直接求每一个区间的最大值就好了. 可是此处成环,那么看一下以下例子. 5 1 -2 ...

  2. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第10章节--SP2013中OAuth概览 应用程序验证

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第10章节--SP2013中OAuth概览  应用程序验证 既然你懂得了什么是应用程序身份.而且知道怎样在SP中创建和设置 ...

  3. 用Visual studio2012在Windows8上开发内核驱动监视线程创建

    在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...

  4. 用Visual studio2012在Windows8上开发内核驱动监视进程创建

    在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破.在Windows 95中,至少应用程序I/O操作是不受限制的,而在Win ...

  5. laravel路由之分组路由

    laravel下的分组路由可以嵌套如下: Route::group(['prefix'=>'admin'],function(){ Route::group(['prefix'=>'dtk ...

  6. C复杂声明举例

    首先,一些国外的研究成果: 一个用英语解析复杂声明的网站:http://cdecl.org 图表说明复杂声明(英):http://c-faq.com/decl/spiral.anderson.html ...

  7. atitit.orm的缺点与orm框架市场占有率,选型attilax总结

    atitit.orm的缺点与orm框架市场占有率,选型attilax总结 1. attilax的orm框架要求 1 2. orm框架市场占有率 2 3. spring jdbc templt 3 4. ...

  8. 【Android】15.0 第15章 广播和通知—本章示例主界面

    分类:C#.Android.VS2015: 创建日期:2016-02-28 一.简介 广播(Broadcast):其功能类似于收音机的广播,你只要调到那个台(只要在接收的类中注册了要接收的广播),就能 ...

  9. IE10/11 滚动条自动隐藏~

    原文: http://www.cnblogs.com/xwgli/p/4463184.html 就是IE10/11滚动条自动隐藏咯~ 原因是bootstrap里面加了一句: @-ms-viewport ...

  10. django 将model转换为字典

    from django.forms.models import model_to_dict from projects.models import ProjectInformation site = ...