题目描述 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 Description

* 第1行: 两个空格分隔的整数V和S

* 第2...V行: 两个空格分隔的整数A_i和B_i

输出描述 Output Description

* 第1行:一个整数,表示FJ可以获得的最大的直径。

样例输入 Sample Input

7 2

6 7

3 4

6 5

1 2

3 2

4 5

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

对于50%的数据,满足V<=100;

对于100%的数据,满足V<=100000

/*
二分答案+贪心
记录以每个节点为根的子树的每条链的长度,如果最长链和次长链的和大于二分出的答案,就减去最长链。
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define N 100010
using namespace std;
int head[N],f[N],g[N],n,m,sum;
struct node
{
int v,pre;
};node e[N*];
void add(int i,int x,int y)
{
e[i].v=y;
e[i].pre=head[x];
head[x]=i;
}
bool cmp(int s1,int s2)
{
return s1>s2;
}
void dfs(int x,int fa,int mid)
{
for(int i=head[x];i;i=e[i].pre)
if(e[i].v!=fa)dfs(e[i].v,x,mid);
int cnt=;
for(int i=head[x];i;i=e[i].pre)
if(e[i].v!=fa)g[++cnt]=f[e[i].v]+;
sort(g+,g+cnt+,cmp);
if(cnt==)
{
f[x]=;return;
}
else if(cnt==)
{
if(g[]<=mid)f[x]=g[];
else sum++,f[x]=;
return;
}
else
{
int i=;
for(;i<=cnt;i++)
if(g[i-]+g[i]<=mid)break;
else sum++;
if(i==cnt+&&g[cnt]>mid)sum++;
f[x]=g[i-];
return;
}
}
bool check(int mid)
{
memset(f,,sizeof(f));
memset(g,,sizeof(g));
sum=;dfs(,,mid);
if(sum>m)return false;
return true;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
int x,y;scanf("%d%d",&x,&y);
add(i*-,x,y);add(i*,y,x);
}
int l=,r=n-,ans=n-;
while(l<=r)
{
int mid=(l+r)>>;
if(check(mid))
{
r=mid-;
ans=mid;
}
else l=mid+;
}
printf("%d",ans);
return ;
}

奶牛健美操(codevs 3279)的更多相关文章

  1. CODEVS 3279 奶牛的健美操

    3279 奶牛健美操 USACO  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 钻石 Diamond 题目描述 Description Farmer John为了保持奶牛们的 ...

  2. BZOJ2097[Usaco2010 Dec] 奶牛健美操

    我猜我这样继续做水题会狗带 和模拟赛的题很像,贪心搞一下. #include<bits/stdc++.h> using namespace std; int read(){ ,f=;cha ...

  3. Usaco 2010 Dec Gold Exercise(奶牛健美操)

    /*codevs 3279 二分+dfs贪心检验 堆版本 re一个 爆栈了*/ #include<cstdio> #include<queue> #include<cst ...

  4. BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP

    BZOJ_2097_[Usaco2010 Dec]Exercise 奶牛健美操_二分答案+树形DP Description Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的 ...

  5. [Usaco2010 Dec]Exercise 奶牛健美操

    [Usaco2010 Dec]Exercise 奶牛健美操 题目 Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的小路上奔跑.这些奶牛的路径集合可以被表示成一个点集和一些连 ...

  6. 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操 二分+贪心

    题目描述 Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的小路上奔跑.这些奶牛的路径集合可以被表示成一个点集和一些连接 两个顶点的双向路,使得每对点之间恰好有一条简单路径. ...

  7. BZOJ——T 2097: [Usaco2010 Dec]Exercise 奶牛健美操

    http://www.lydsy.com/JudgeOnline/problem.php?id=2097 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit:  ...

  8. 问题 C: 「Usaco2010 Dec」奶牛健美操O(∩_∩)O

    题目描述 Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间的小路上奔跑.这些奶牛的路径集合可以被表示成一个点集和一些连接 两个顶点的双向路,使得每对点之间恰好有一条简单路径.  ...

  9. [bzoj 2097]奶牛健美操

    题目描述 对于一棵n个点的树,删除k条边,使得所有联通块直径最大值最小 题解 首先二分联通块直径最大值的最小值. 那么这个能否达成的判定变成了一个类似树形dp的东西 对于一个子树,删除一条边可以删除整 ...

随机推荐

  1. Mac Pro 修改环境变量

    参考:Ubuntu 12 修改环境变量 [实战] 把 php.php-fpm.nginx.mysql 的相关命令路径添加到 用户环境变量 $ vim ~/.bash_profile alias ll= ...

  2. CPU核数跟多线程的关系

    一直以来有这样的疑惑,单核CPU适合多线程吗?是不是几个核的CPU开几个线程是最合适的? 今天就这一问题查了一些资料,现整理如下: 要说多线程就离不开进程,进程和线程的区别在这里就不详细说了,只将关键 ...

  3. [转]看了这个才发现jQuery源代码不是那么晦涩

    很多人觉得jquery.ext等一些开源js源代码 十分的晦涩,读不懂,遇到问题需要调试也很费劲.其实我个人感觉主要是有几个方面的原因: 对一些js不常用的语法.操作符不熟悉 某个function中又 ...

  4. iOS 开发 初级:应用内购买 In-App Purchase

    http://blog.csdn.net/songrotek/article/details/8680415 现在有很多应用都使用了In-App Purchase,虽然对于很多用户来说,可能并不喜欢甚 ...

  5. C++ 复制构造函数

    C++类的设计中,如果某些函数没有显式定义,C++会自动生成,复制构造函数便是其中之一,其他的还有默认构造函数.赋值操作符.默认析构函数.地址操作符.一个类的复制构造函数的原型一般为: Class_n ...

  6. linux中diff命令用法

    diff 命 令是 linux上非常重要的工具,用于比较文件的内容,特别是比较两个版本不同的文件以找到改动的地方.diff在命令行中打印每一个行的改动.最新版 本的diff还支持二进制文件.diff程 ...

  7. OpenCV成长之路(8):直线、轮廓的提取与描述

    基于内容的图像分析的重点是提取出图像中具有代表性的特征,而线条.轮廓.块往往是最能体现特征的几个元素,这篇文章就针对于这几个重要的图像特征,研究它们在OpenCV中的用法,以及做一些简单的基础应用. ...

  8. r-cnn学习(二)

    faster r-cnn 1.问题 在fast r-cnn中,proposals已经成为速度提高的瓶颈.在本文中,使用深度网络来计算proposals, 使得与检测网络的计算量相比,proposals ...

  9. SVN迁移到Git的过程(+ 一些技巧)

    SVN迁移到Git的过程(+ 一些技巧) 李顺利 Key Words SVN,Git,Clone,Conversion,Tips,VCS,Pro Git 关于在VCS中SVN和Git之间的迁移(Clo ...

  10. django ATOMIC_REQUESTS

    在数据库配置中,如果配置了此属性为True,如下: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.xxx', 'NAME': '', ...