题目

在一片草原上有 \(N\) 个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝。更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连。换句话讲,这些兔子窝之前的路径构成一张 \(N\) 个点、\(M\) 条边的无向连通图,而度数大于2的点至多有1个。

兔子们决定把其中 \(K\) 个兔子窝扩建成临时避难所。当危险来临时,每只兔子均会同时前往距离它最近的避难所躲避,路程中花费的时间在数值上等于经过的路径条数。为了在最短的时间内让所有兔子脱离危险,请你安排一种建造避难所的方式,使最后一只到达避难所的兔子所花费的时间尽量少。

分析

显然二分答案,然后判断能不能成功

首先考虑一条链,它需要的最少的避难所数量是 \(\lceil \frac{len}{2 \times mid + 1} \rceil\)

就是能不放就不放

环呢?

然后发现只有一个度数大于 \(2\) 的点

记为 \(rt\)

它必然是环上的点

如果把它删了,就只剩下一堆链

于是我们枚举一个可以覆盖 \(rt\) 的,把这个点能覆盖的所有点都删了

图只剩下一堆链

再统计每条链的长度 \(len\),用上面的贪心办法算

算完后如果结果小于等于 \(k\),那就成功了

于是就是 \(O(N^2 \log N)\) 的

\(Code\)

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std; const int N = 1005 , M = 1505;
int n , m , k , tot , rt , h[N] , vis[N] , deg[N] , X[N];
struct edge{
int to , nxt;
}e[M * 2]; inline void add(int x , int y){e[++tot] = edge{y , h[x]} , h[x] = tot;} void choose(int x , int d , int mid)
{
if (d <= mid) X[++X[0]] = x;
else return;
vis[x] = 1;
for(register int i = h[x]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!vis[v]) choose(v , d + 1 , mid);
}
} void del(int x , int d , int mid)
{
if (d > mid) return;
vis[x] = 1;
for(register int i = h[x]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!vis[v]) del(v , d + 1 , mid);
}
} int Get(int x)
{
int res = 1; vis[x] = 1;
for(register int i = h[x]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!vis[v]) res += Get(v);
}
return res;
} int check(int mid)
{
if (rt == 0) return (int)ceil(1.0 * n / (2 * mid + 1));
memset(vis , 0 , sizeof vis);
int num = 0; X[0] = 0 , choose(rt , 0 , mid);
for(register int i = 1; i <= X[0]; i++)
{
memset(vis , 0 , sizeof vis);
del(X[i] , 0 , mid) , num = 1;
for(register int i = 1; i <= n; i++)
if (!vis[i]) num += (int)ceil(1.0 * Get(i) / (2 * mid + 1));
if (num <= k) return 1;
}
return 0;
} int main()
{
freopen("rabbit.in" , "r" , stdin);
freopen("rabbit.out" , "w" , stdout);
scanf("%d%d%d" , &n ,&m , &k);
int x , y;
for(register int i = 1; i <= m; i++)
scanf("%d%d" , &x , &y) , add(x , y) , add(y , x) , deg[x]++ , deg[y]++;
for(register int i = 1; i <= n; i++)
if (deg[i] >= 3){rt = i; break;}
if (n == 1){printf("0"); return 0;}
int l = 1 , r = n , mid , res;
while (l <= r)
{
mid = (l + r) >> 1;
if (check(mid)) res = mid , r = mid - 1;
else l = mid + 1;
}
printf("%d" , res);
}

JZOJ 4896. 【NOIP2016提高A组集训第16场11.15】兔子的更多相关文章

  1. JZOJ 【NOIP2016提高A组集训第16场11.15】兔子

    JZOJ [NOIP2016提高A组集训第16场11.15]兔子 题目 Description 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3 ...

  2. JZOJ 【NOIP2016提高A组集训第16场11.15】SJR的直线

    JZOJ [NOIP2016提高A组集训第16场11.15]SJR的直线 题目 Description Input Output Sample Input 6 0 1 0 -5 3 0 -5 -2 2 ...

  3. 【JZOJ4895】【NOIP2016提高A组集训第16场11.15】三部曲

    =v= 因为外来的入侵,国王决定在某些城市加派士兵.所有城市初始士兵数量为0.当城市 被加派了k名士兵时.城市i的所有子城市需要被加派k+1名士兵.这些子城市的所有子城市需要被加派k+2名士兵.以此类 ...

  4. 【JZOJ4894】【NOIP2016提高A组集训第16场11.15】SJR的直线

    题目描述 数据范围 解法 考虑逐次加入每一条直线. 对于当前已加入的直线集合L,现在要新加入一条直线l. 那么它产生的贡献,与平行线有关. 对于任意三条直线,如果其中任意两条平行,那么将不做贡献. 所 ...

  5. 【JZOJ4896】【NOIP2016提高A组集训第16场11.15】兔子

    题目描述 在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝.更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连.换句话讲,这些兔子窝之 ...

  6. 【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 分析 如果暴力枚举每个人被分到哪 ...

  7. 【NOIP2016提高A组集训第14场11.12】随机游走——期望+树形DP

    好久没有写过题解了--现在感觉以前的题解弱爆了,还有这么多访问量-- 没有考虑别人的感受,没有放描述.代码,题解也写得歪歪扭扭. 并且我要强烈谴责某些写题解的代码不打注释的人,像天书那样,不是写给普通 ...

  8. 【JZOJ4841】【NOIP2016提高A组集训第4场11.1】平衡的子集

    题目描述 夏令营有N个人,每个人的力气为M(i).请大家从这N个人中选出若干人,如果这些人可以分成两组且两组力气之和完全相等,则称为一个合法的选法,问有多少种合法的选法? 数据范围 40%的数据满足: ...

  9. 【NOIP2016提高A组集训第14场11.12】随机游走

    题目 YJC最近在学习图的有关知识.今天,他遇到了这么一个概念:随机游走.随机游走指每次从相邻的点中随机选一个走过去,重复这样的过程若干次.YJC很聪明,他很快就学会了怎么跑随机游走.为了检验自己是不 ...

  10. 【NOIP2016提高A组集训第13场11.11】最大匹配

    题目 mhy12345学习了二分图匹配,二分图是一种特殊的图,其中的点可以分到两个集合中,使得相同的集合中的点两两没有连边. 图的"匹配"是指这个图的一个边集,里面的边两两不存在公 ...

随机推荐

  1. vue3 + element plus 使用字节跳动图标

    使用场景: 提一下vue2 用法>> 下面回到正题 vue3 用法 1  安装包: npm install @icon-park/vue-next --save 2  字节跳动图标库取图地 ...

  2. 【笔面试真题】Flow++赋乐科技-面试-2022年1月25日

    一.概括 涉及JVM的GC.三色标记 并发部分的锁 Java集合中的hashmap.list kafka中ISR相关 硬件相关-有无DMA 自定义类(代码) 缺陷:锁.list 二.JVM相关内容 1 ...

  3. 【大数据面试】ClickHouse:介绍、特点、数据类型、引擎、操作、副本、分片

    1.介绍 开源的列式存储数据库(DBMS),由C++编写,用于在线分析处理查询(OLAP) 可以通过SQL查询实时生成分析数据报告 解释: DBMS:数据库管理系统 常见的列式存储数据库:Hbase. ...

  4. Java/JDK各版本主要特性汇总

    目录 Java18(2022.3) Java17(2021.9)(LTS版本) Java16(2021.3) Java15(2020.9) Java14(2020.3) Java13(2019.9) ...

  5. dubbo2升级到dubbo3实践

    dubbo当前版本 2.7.3 期望升级到 3.0.11. 升级过程 maven依赖变更 <dependency> <groupId>org.apache.dubbo</ ...

  6. 第一百一十四篇: JS数组Array(三)数组常用方法

    好家伙,本篇为<JS高级程序设计>第六章"集合引用类型"学习笔记   1.数组的复制和填充 批量复制方法 copyWithin(),以及填充数组方法fill(). 这两 ...

  7. [OpenCV实战]35 使用Tesseract和OpenCV实现文本识别

    目录 1 如何在Ubuntu和windows上安装Tesseract 1.1 在ubuntu18.04上安装Tesseract4 1.2 在Ubuntu 14.04,16.04,17.04,17.10 ...

  8. LVGL 中图片使用问题

    此笔记主要是记录在 LVGL 中使用图片的几种方式,以及使用过程中遇到的问题.最近在 ARM linux 中使用 LVGL 时,发现加载图片变得很卡,一开始还好,当连续加载的图片变多后,特别是动画的过 ...

  9. TCP通信的概述(上)-TCP通信的概述(下)

    TCP通信的概述(上) TCP通信的概述(下)

  10. 局部内部类定义-局部内部类的final问题

    局部内部类定义 定义格式: 修饰符 class 外部类名称 { 修饰符 返回值类型 外部类方法名(参数列表){ class 局部内部类名称{// ... } } } 小杰一下类的权限修饰符: publ ...