【BZOJ2067】[Poi2004]SZN 二分+树上贪心
【BZOJ2067】[Poi2004]SZN
Description
Input
Output
Sample Input
7 8
4 5
5 6
1 2
3 2
9 8
2 5
5 8
Sample Output
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值需要特殊处理。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=10010;
int n,m,ans,cnt,lim,flag;
int to[maxn<<1],next[maxn<<1],head[maxn],d[maxn];
int g[maxn],f[maxn];
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
bool check(int x)
{
int i,j;
for(i=1,j=m;i<j;i++,j--)
{
if(i==x) i++;
if(j==x) j--;
if(g[i]+g[j]>lim) return 0;
}
return 1;
}
void dfs(int x,int fa)
{
int i;
for(i=head[x];i!=-1;i=next[i]) if(to[i]!=fa) dfs(to[i],x);
for(m=0,i=head[x];i!=-1;i=next[i]) if(to[i]!=fa) g[++m]=f[to[i]]+1;
if(x==1)
{
sort(g+1,g+m+1);
flag&=check((m&1)?m:0);
return ;
}
if(!(m&1)) g[++m]=0;
sort(g+1,g+m+1);
int l=1,r=m+1,mid;
while(l<r)
{
mid=(l+r)>>1;
if(g[mid]+1<=lim&&check(mid)) r=mid;
else l=mid+1;
}
if(r==m+1) flag=0;
f[x]=g[r];
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,a,b,l=1,r=n;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a),d[a]++,d[b]++;
for(ans=i=1;i<=n;i++) ans+=(d[i]-1)>>1;
while(l<r)
{
flag=1,lim=(l+r)>>1,dfs(1,0);
if(flag) r=lim;
else l=lim+1;
}
printf("%d %d",ans,r);
return 0;
}
【BZOJ2067】[Poi2004]SZN 二分+树上贪心的更多相关文章
- bzoj 2525: [Poi2011]Dynamite【二分+树上贪心】
一眼二分.然后重点是树上贪心部分 长得像dp一样,设mn为子树内已炸点的最浅点,mx为子树内没有炸并且需要炸的最深点,然后转移直接从子树继承即可 然后是判断当前u点是否需要炸,当mx[u]+mn[u] ...
- bzoj 2067 [Poi2004]SZN——二分+贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2067 最少的线段可以贪心地想出来.(结果还是写错了)就是偶数孩子可以自己配对,奇数孩子要带一 ...
- bzoj2067: [Poi2004]SZN
Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一些顶点和特定数量的边构成. 每个顶点都可以连向 ...
- 2067: [Poi2004]SZN——树上贪心+二分
题目大意: 给一棵树.求用最少的链覆盖这棵树(链不能相交),在这个基础上求最长的链最短可以是多少. n<=10000 题解: 肯定先处理第一问: 答案:$\sum_(du[i]-1)/2+1$ ...
- 【BZOJ2067】SZN(二分,动态规划,贪心)
[BZOJ2067]SZN(二分,动态规划,贪心) 题面 权限题额 Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图 ...
- 【BZOJ2067】[Poi2004]SZN
题解: 比上一题水多了 首先树上贪心,肯定要考虑儿子 然后我们会发现这个东西就是要先把儿子连起来 然后如果儿子个数为奇数我们可以把这一条和它连向父亲的并在一起 由于根没有父亲所以要单独考虑 答案就是s ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- CodeForces - 363D --二分和贪心
题目:CodeForces - 363D 题意:给定n个学生,其中每个学生都有各自的私己钱,并且自己的私己钱只能用在自己买自行车,不能给别人. 给定m个自行车,每个自行车都有一个价格. 给定公有财产a ...
- 【BZOJ1816】[CQOI2010]扑克牌(二分,贪心)
[BZOJ1816][CQOI2010]扑克牌(二分,贪心) 题面 BZOJ 题解 看了一眼这题,怎么这么眼熟?woc,原来\(xzy\)的题目是搬的这道啊... 行,反正我考的时候也切了,这数据范围 ...
随机推荐
- tcp_handle_req: Made 4 read attempts but message is not complete yet - closing connection
一.现象 测试opensips时遇到这么一个错误提示: ERROR:core:tcp_handle_req: Made read attempts but message is not complet ...
- python 中 numpy array 中的维度
简介 numpy 创建的数组都有一个shape属性,它是一个元组,返回各个维度的维数.有时候我们可能需要知道某一维的特定维数. 二维情况 >>> import numpy as np ...
- tp请求和响应
一.请求参数 use think\Request; 1.获取方法如下: http://w.tp.com/index/index/index/user/AAA $this->request-> ...
- T-sql for xml path使用(转)
参考: http://www.cnblogs.com/langhua/p/4193161.html //用法: FOR XML PATH 方法是用于将查询结果集以XML形式展示 sql: p.Cont ...
- SQL Server2005 两台服务器上的数据库互相同步(转载)
1.1测试环境 Item 发布机 A 订阅机 B OS Windows 2003 Server Windows 2003 Server SQL SQL Server 2005 企业版 SQL Serv ...
- unity, GUIStyle and Skin
例1: using UnityEngine; using System.Collections; using UnityEditor; using System.Collections.Generic ...
- [Informix] unload load
select tabname from systables where tabname like 'aa%' select * from syscolumns where tabname like ...
- 【原创】k8s源代码分析-----kubelet(1)主要流程
本人空间链接http://user.qzone.qq.com/29185807/blog/1460015727 源代码为k8s v1.1.1稳定版本号 kubelet代码比較复杂.主要是由于其担负的任 ...
- mount -o remount,rw / (这是个求命的命令)
当系统无法启动的时候.我们会前进入单用户模式(正常情况下单用户莫式是权限是正常的,只在在无法启动的情况下, 再进入单用户模式,权限才会是只读),这时候没有对文件的修改权限(所有的文件都是只读) 用这条 ...
- jQuery新建HTML Element
举个例: 创建一个<i>HelloWorld.</i> var italicText = $("<i></i>").text(&qu ...