bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操 (二分答案+贪心)
来源:互联网 发布:网站源码网 编辑:程序博客网 时间:2024/04/20 21:05
2097: [Usaco2010 Dec]Exercise 奶牛健美操
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 305 Solved: 150
[Submit][Status][Discuss]
Description
Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的小路上奔跑。这些奶牛的路径集合可以被表示成一个点集和一些连接 两个顶点的双向路,使得每对点之间恰好有一条简单路径。简单的说来, 这些点的布局就是一棵树,且每条边等长,都为1。 对于给定的一个奶牛路径集合,精明的奶牛们会计算出任意点对路径的最大值, 我们称之为这个路径集合的直径。如果直径太大,奶牛们就会拒绝锻炼。 Farmer John把每个点标记为1..V (2 <= V <= 100,000)。为了获得更加短 的直径,他可以选择封锁一些已经存在的道路,这样就可以得到更多的路径集合, 从而减小一些路径集合的直径。 我们从一棵树开始,FJ可以选择封锁S (1 <= S <= V-1)条双向路,从而获得 S+1个路径集合。你要做的是计算出最佳的封锁方案,使得他得到的所有路径集合 直径的最大值尽可能小。 Farmer John告诉你所有V-1条双向道路,每条表述为:顶点A_i (1 <= A_i <= V) 和 B_i (1 <= B_i <= V; A_i!= B_i)连接。 我们来看看如下的例子:线性的路径集合(7个顶点的树) 1---2---3---4---5---6---7 如果FJ可以封锁两条道路,他可能的选择如下: 1---2 | 3---4 | 5---6---7 这样最长的直径是2,即是最优答案(当然不是唯一的)。
Input
* 第1行: 两个空格分隔的整数V和S * 第2...V行: 两个空格分隔的整数A_i和B_i
Output
* 第1行:一个整数,表示FJ可以获得的最大的直径。
Sample Input
7 2
6 7
3 4
6 5
1 2
3 2
4 5
6 7
3 4
6 5
1 2
3 2
4 5
Sample Output
2
HINT
Source
Gold
题解:二分答案+贪心
先二分一个最大值,将一个点所能到达的树链按长度从大到小排序,如果最长链+次长链>最大值,就将最长链砍断,知道最长链+次长链<=最大值为止,记录封锁道路的条数。
如果记录的条数大于要求的条数,就把左指针右移,否则将右指针左移。
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define N 200003using namespace std;int point[N],next[N],v[N],c[N],tot;int m,n,ans,size,maxn,st[N],f[N];void add(int x,int y){tot++; next[tot]=point[x]; point[x]=tot; v[tot]=y; c[tot]=1;tot++; next[tot]=point[y]; point[y]=tot; v[tot]=x; c[tot]=1;}int cmp(int x,int y){return x>y;}int dfs(int x,int fa){int cnt=0; f[x]=0;for (int i=point[x];i;i=next[i]) if (v[i]!=fa) dfs(v[i],x);for (int i=point[x];i;i=next[i]) if (v[i]!=fa) st[++cnt]=f[v[i]]+1;sort(st+1,st+cnt+1,cmp);if (cnt==0) return f[x]=0;if (cnt==1) if (st[1]>maxn) {size++;return f[x]=0; } else return f[x]=st[1];int i=2;while (st[i-1]+st[i]>maxn&&i<=cnt) { size++; i++; }if (i==cnt+1&&st[cnt]>maxn) size++;return f[x]=st[i-1];}bool pd(int x){maxn=x;size=0; dfs(1,0);if (size<=m) return true;else return false;}int main(){scanf("%d%d",&n,&m);for (int i=1;i<n;i++){int x,y;scanf("%d%d",&x,&y);add(x,y);} int l=1; int r=n; ans=n; while (l<=r) { int mid=(l+r)/2; if (pd(mid)) ans=min(ans,mid),r=mid-1; else l=mid+1;}printf("%d\n",ans);}
0 0
- bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操 (二分答案+贪心)
- BZOJ 2097: [Usaco2010 Dec]Exercise 奶牛健美操 二分 贪心
- BZOJ 2097 [Usaco2010 Dec]Exercise 奶牛健美操 二分
- BZOJ 2097 USACO 2010 Dec Gold Exercise 奶牛健美操 二分答案 树形DP 贪心
- 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操 二分答案+树形dp+贪心
- BZOJ 2097 Exercise 奶牛健美操 二分答案+树形DP+贪心
- [BZOJ2097][Usaco2010 Dec]Exercise 奶牛健美操(二分+树形dp+贪心)
- [BZOJ2097][Usaco2010 Dec]Exercise 奶牛健美操(二分+树形dp+贪心)
- bzoj2097[Usaco2010 Dec]Exercise 奶牛健美操
- 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操
- [bzoj2097][Usaco2010 Dec]Exercise 奶牛健美操
- BZOJ2097: [Usaco2010 Dec]Exercise 奶牛健美操
- bzoj 1690: [Usaco2007 Dec]奶牛的旅行 spfa+二分答案
- bzoj1690 [Usaco2007 Dec]奶牛的旅行(最优比率环,二分答案+spfa判负环)
- bzoj 1779: [Usaco2010 Hol]Cowwar 奶牛战争 (网络流)
- [bzoj2016][Usaco2010]Chocolate Eating(二分+贪心)
- bzoj 2016: [Usaco2010]Chocolate Eating (二分)
- BZOJ 1776: [Usaco2010 Hol]cowpol 奶牛政坛 贪心lca/点分治
- C++/C语言内存类别及其分配——堆栈区别
- CSS构造原则及CSS与浏览器兼容性
- HDU 2669 Romantic扩展欧几里得
- 构造器是否可以被重写?
- JS面向对象(一)
- bzoj 2097: [Usaco2010 Dec]Exercise 奶牛健美操 (二分答案+贪心)
- MP3项目的供电问题
- 运算符号优先级
- 图片路径L:While reading /Volumes/data2/project/ChildStory/ChildStory/nav_bar.png pngcrush caught libpng
- OSI参考模型
- Android开机启动流程
- <今年你不能错过的事>
- C++中类的构造函数
- 打字游戏-第一个小项目