[POI2004] SZN
Description
给定\(N(N\leq 10000)\)个点的树,要求用最少的路径覆盖树边。路径之间可以有交点,不能有交边。问最少需要几条路径以及在第一问的基础上最长的路径最短是多少?
Solution
第一问对于每个点考虑它与它的孩子之间的边
如果能两两消掉是最好的,贡献就是\(\frac{deg[i]-1}2\),否则就要额外多出一条边,贡献是\(\frac{deg[i]-1}2+1\)。
第二问就是二分答案了
判断\(\leq mid\) 是否可行
可以一遍 \(dfs\) 求出 \(f[i]\) 表示第 \(i\) 个点最短向下延伸多长
如何求这个 \(f[i]\) ?
需要对点的孩子个数分奇偶性讨论
如果它有偶数个孩子,那么最理想的情况就是让他们两两匹配,这个点的 \(f\) 值为 \(0\)。
如果事与愿违(我写个博客怎么都这么多骚话),就可以尝试拿出两个孩子,让一个孩子的链断在这个点,这个点接上另一个孩子的链,其他孩子两两匹配。
如果有奇数个孩子,那就是拿出一个孩子,让这个点接上这个孩子的链,其他孩子两两匹配。
判断两两匹配可以再套个二分。
Code
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<cctype>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using std::min;
using std::max;
using std::swap;
using std::vector;
const int N=10005;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define mp(A,B) std::make_pair(A,B)
int head[N],f[N];
int n,cnt,g[N],deg[N];
struct Edge{
int to,nxt;
}edge[N<<1];
void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
}
int getint(){
int X=0,w=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
if(w) return -X;return X;
}
bool check(int l,int r,int x,int mid){
while(l<r){
if(l==x) l++;
if(r==x) r--;
if(g[l]+g[r]>mid) return 0;
l++,r--;
} return 1;
}
bool dfs(int now,int fa,int x){
int cnts=0;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;cnts++;
if(to!=fa) if(!dfs(to,now,x)) return 0;
if(f[to]+1>x) return 0;
} if(cnts==1 and now!=1) return f[now]=0,1;
int pos=0;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa) continue;
g[++pos]=f[to]+1;
} std::sort(g+1,g+1+pos);
if(pos%2==0){ //偶数
int flag=0;
for(int i=1;i<=pos/2;i++)
if(g[i]+g[pos-i+1]>x)
flag=1;
if(!flag) return f[now]=0,1;
if(now==1) return 0;
int l=1,r=pos-1,ans=0;
while(l<=r){
int mid=l+r>>1;
if(g[mid]>x) {l=mid+1;continue;}
if(check(1,pos-1,mid,x)) ans=mid,r=mid-1;
else l=mid+1;
} if(!ans) return 0;
f[now]=g[ans];return 1;
} else{
if(pos==1) return g[1]<=x?f[now]=g[1],1:0;
int l=1,r=pos,ans=0;
while(l<=r){
int mid=l+r>>1;
if(g[mid]>x) {l=mid+1;continue;}
if(check(1,pos,mid,x)) ans=mid,r=mid-1;
else l=mid+1;
} if(!ans) return 0;
f[now]=g[ans];return 1;
}
}
signed main(){
// system("fc 11.out out.txt");
// freopen("11.in","r",stdin);//freopen("out.txt","w",stdout);
n=getint();
for(int i=1;i<n;i++){
int x=getint(),y=getint();
add(x,y);add(y,x);deg[x]++;deg[y]++;
} int ans=1;
for(int i=1;i<=n;i++) ans+=(deg[i]-1)/2;
printf("%d ",ans);
int l=0,r=n-1;ans=0;
while(l<=r){
int mid=l+r>>1;
if(dfs(1,0,mid)){
if(f[1]<=mid) ans=mid,r=mid-1;
else l=mid+1;
}
else l=mid+1;
} printf("%d\n",ans);
return 0;
}//youngneal
[POI2004] SZN的更多相关文章
- 【BZOJ2067】[Poi2004]SZN 二分+树上贪心
[BZOJ2067][Poi2004]SZN Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一 ...
- 2067: [Poi2004]SZN——树上贪心+二分
题目大意: 给一棵树.求用最少的链覆盖这棵树(链不能相交),在这个基础上求最长的链最短可以是多少. n<=10000 题解: 肯定先处理第一问: 答案:$\sum_(du[i]-1)/2+1$ ...
- bzoj2067: [Poi2004]SZN
Description String-Toys joint-stock 公司需要你帮他们解决一个问题. 他们想制造一个没有环的连通图模型. 每个图都是由一些顶点和特定数量的边构成. 每个顶点都可以连向 ...
- 【BZOJ2067】[Poi2004]SZN
题解: 比上一题水多了 首先树上贪心,肯定要考虑儿子 然后我们会发现这个东西就是要先把儿子连起来 然后如果儿子个数为奇数我们可以把这一条和它连向父亲的并在一起 由于根没有父亲所以要单独考虑 答案就是s ...
- bzoj 2067 [Poi2004]SZN——二分+贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2067 最少的线段可以贪心地想出来.(结果还是写错了)就是偶数孩子可以自己配对,奇数孩子要带一 ...
- bzoj 2067: [Poi2004]SZN【贪心+二分+树形dp】
第一问就是Σ(deg[u]-1)/2+1 第二问是二分,判断的时候考虑第一问的贪心规则,对于奇度数的点,两两配对之后一条延伸到上面:对于欧度数的点,两两配对或者deg[u]-2的点配对,然后一条断在这 ...
- Noip前的大抱佛脚----赛前任务
赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- 【BZOJ2073】[POI2004]PRZ 状压DP
[BZOJ2073][POI2004]PRZ Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍 ...
随机推荐
- CentOS6.9安装Python-3.6.3
CentOS6.9上默认安装的python版本是2.6的.因为系统自带的python会被系统很多软件环境依赖使用,所以不要卸载原来的Python版本,根据需要进行安装新版本即可,本人此处安装的是3.6 ...
- ABP框架系列之六:(Value-Objects-值对象)
Introduction "An object that represents a descriptive aspect of the domain with no conceptual i ...
- (PMP)第6章-----项目进度管理
6.1 规划进度管理 输入 工具与技术 输出 1.项目章程 2.项目管理计划 (范围管理计划, 开发方法) 3.事业环境因素 4.组织过程资产 1.专家判断 2.数据分析 3.会议 1.进度管理计划 ...
- pyhon_day1 格式化输出
格式化输出 我们在写Python的在很多时候输出的内容需要规定格式的,这样就引入到了格式化输出 定义: 盗用下大咖的例子: ------------ info of alex ----------- ...
- elasticsearch之入门hello(java)一
1.书写pom.xml文件 <dependencies> <dependency> <groupId>org.elasticsearch</groupId&g ...
- (转载)linux 常用命令
出处:http://www.cnblogs.com/vamei $ 命令行提示符 粗体表示命令 斜体表示参数 filename, file1, file2 都是文件名.有时文件名有后缀,比如file. ...
- 附加题2 :git 简单练习
目的: 练习git 基本操作 理解版本管理 Task 1:在码云上新建一个项目,项目命名 『Helloworld』 ,设置为公开访问. step 0: 在你计算机安装git.参照互联网教程<gi ...
- Real World Parsec --- 一个简便易学的 解释器
学习链接如下: http://bms.tratao.com/desktop/doc/0c3802e4ee404a71407f34996eff98ef 另外的解析器 ANTLR,学过一阵子,比较难,没应 ...
- 背水一战 Windows 10 (66) - 控件(WebView): 监听和处理 WebView 的事件
[源码下载] 背水一战 Windows 10 (66) - 控件(WebView): 监听和处理 WebView 的事件 作者:webabcd 介绍背水一战 Windows 10 之 控件(WebVi ...
- MSRA-TD5000数据集使用详解
中文检测的数据集,目前最火的应该是清华的CTW,https://ctwdataset.github.io/ 但是它的数据集只存储在微云和google driver,微云空间受限不能完全保存,所以下载的 ...