博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GYM 101964 C(二分答案)
阅读量:5249 次
发布时间:2019-06-14

本文共 1475 字,大约阅读时间需要 4 分钟。

题意:

    给你一个n个结点的树,其中有一部分结点是黑色的。现在让你选取m个黑色结点,使得这些黑色结点所形成的集合的中,任意两点间的最远距离最小。让你求出这个最远距离。

题目分析:

    首先,题目中的”使得最大值最小“这句话就非常符合二分的条件了。因此我们考虑对答案(两个黑点的最远的距离)进行二分。

    现在就要考虑如何进行check。

    对于每一个二分值k,我们考虑先用bfs遍历整颗树,然后利用bfs的性质(距离当前点的所有已bfs过且小于等于d的那些点,他们之间两两距离也小于等于k),找出满足距离等于k的对应的一个个点集。之后我们可以用dfs去遍历这些点集,判断点集中的黑点的个数与需要选取的黑点个数m之间的关系即可(如果数量>=n,则右指针左移动;反之左指针右移)。

代码:

#include 
#define maxn 105using namespace std;vector
vec[maxn];int vis[maxn];//用vis数组去区分点的不同的集合int a[maxn];queue
que;int n,m;int ans=0;int dfs(int now,int fa,int all,int dis){ int res=a[now]; if(dis==all) return res; for(auto &it:vec[now]){ if(!vis[it]||it==fa) continue; res+=dfs(it,now,all,dis+1); } return res;}bool check(int k){//二分的check,本质上为一个bfs memset(vis,0,sizeof(vis)); while(!que.empty()) que.pop(); que.push(1); while(!que.empty()){//bfs选取部分点集 int now=que.front(); que.pop(); vis[now]=1; int tmp=dfs(now,0,k,0);//通过dfs获取这个集合的黑点的个数 if(tmp>=m) return 1; for(auto &it:vec[now]){ if(vis[it]) continue; que.push(it); } } return 0;}int main(){ //freopen("in.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=0;i
>1; if(check(mid)) r=mid; else l=mid+1; //cout<
<<" "<
<

 

转载于:https://www.cnblogs.com/Chen-Jr/p/11007175.html

你可能感兴趣的文章
【识记】 域名备案
查看>>
STL uva 11991
查看>>
MY SQL的下载和安装
查看>>
自定义OffMeshLink跳跃曲线
查看>>
寄Android开发Gradle你需要知道的知识
查看>>
简述spring中常有的几种advice?
查看>>
学习Redux之分析Redux核心代码分析
查看>>
ABAP 创建和调用WebService
查看>>
C# 实例化顺序
查看>>
CSS水平垂直居中总结
查看>>
委托又给我惹麻烦了————记委托链的取消注册、获取返回值
查看>>
ps怎么把白色背景变透明
查看>>
gource 安装教程
查看>>
字符串转 Boolean 的正确方式
查看>>
给你的网站404页面加上“宝贝寻亲”公益页面
查看>>
整理推荐的CSS属性书写顺序
查看>>
协程, IO阻塞模型 和 IO非阻塞模型
查看>>
ServerSocket和Socket通信
查看>>
css & input type & search icon
查看>>
jQuery插件开发详细教程
查看>>