清北学堂模拟day6 兔子
【问题描述】
在一片草原上有N个兔子窝,每个窝里住着一只兔子,有M条路径连接这些窝。更特殊地是,至多只有一个兔子窝有3条或更多的路径与它相连,其它的兔子窝只有1条或2条路径与其相连。换句话讲,这些兔子窝之前的路径构成一张N个点、M条边的无向连通图,而度数大于2的点至多有1个。
兔子们决定把其中K个兔子窝扩建成临时避难所。当危险来临时,每只兔子均会同时前往距离它最近的避难所躲避,路程中花费的时间在数值上等于经过的路径条数。为了在最短的时间内让所有兔子脱离危险,请你安排一种建造避难所的方式,使最后一只到达避难所的兔子所花费的时间尽量少。
【输入】
第一行有3个整数N,M,K,分别表示兔子窝的个数、路径数、计划建造的避难所数。
接下来M行每行三个整数x,y,表示第x个兔子窝和第y个兔子窝之间有一条路径相连。任意两个兔子窝之间至多只有1条路径。
【输出】
一个整数,表示最后一只到达避难所的兔子花费的最短时间。
【输入输出样例1】
rabbit.in |
rabbit.out |
5 5 2 1 2 2 3 1 4 1 5 4 5 |
1 |
见选手目录下的rabbit / rabbit1.in与rabbit / rabbit1.out
【输入输出样例1说明】
在第2个和第5个兔子窝建造避难所,这样其它兔子窝的兔子最多只需要经过1条路径就可以到达某个避难所。
【输入输出样例2】
见选手目录下的rabbit / rabbit2.in与rabbit / rabbit2.out
【数据规模与约定】
对于30%的数据,N≤15,K≤4;
对于60%的数据,N≤100;
对于100%的数据,1≤K≤N≤1,000,1≤M≤1,500
/*
求到达时间最晚的兔子的最早到达时间
二分答案X,求解至少建几个避难所,使得每个兔窝在距离X的范围内至少有一个避难所
枚举住在“根”的兔子去往的避难所的位置,记为A
令与A距离不超过X的兔子都前往A
剩下的兔窝被分成若干条链,容易计算最少需要建立几个避难所
判断总数是否超过K个
*/
#include <cstdio>
#include <cstring>
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std; const int maxn = ;
struct data {
int adj, next;
} r[ * maxn];
int g[maxn], tot, du[maxn], rt;
void ins(int a, int b)
{
r[++tot].adj = b;
r[tot].next = g[a];
g[a] = tot;
}
int n, m, k; struct road {
bool circle;
int len;
};
road d[maxn], d2[maxn];
int cnt; int calc(int len, int t)//计算链中需要建造的避难所的数量,每t*2+1个点建一个
{
if (len <= ) return ;
return (len - ) / (t * + ) + ;
} bool check(int t)
{
int mind = n + ;
for (int i = ; i < cnt; ++i)
{
for (int kp = ; kp <= d[i].len && kp <= t; ++kp)
{
int tot;
if (!d[i].circle)
tot = calc(d[i].len - kp - t, t);
else tot = calc(d[i].len - kp - t + (kp - t), t);//注意环的计算,实际上避难所A可以影响到深度比较大的节点
++tot;
for (int j = ; j < cnt; ++j)
if (j != i)
{
if (!d[j].circle)
tot += calc(d[j].len + (kp - t), t);//注意A对他的影响
else
tot += calc(d[j].len + * (kp - t), t);
}
mind = min(mind, tot);
}
}
return mind <= k;
} void binary()
{
int l = , r = n;
while (l < r)
{
int mid = (l + r) >> ;
if (check(mid)) r = mid;
else l = mid + ;
}
printf("%d\n", r);
} void init();
int main()
{
freopen("rabbit.in", "r", stdin);
freopen("rabbit.out", "w", stdout); init();
binary();
return ;
}
bool col[maxn];
int t0;
void dfs(int x)
{
col[x] = ;
++d[cnt].len;
for (int p = g[x]; p != -; p = r[p].next)
if (col[r[p].adj] == )
dfs(r[p].adj);
else if (r[p].adj == rt && x != t0)
d[cnt].circle = ;
}
void init()
{
scanf("%d%d%d", &n, &m, &k);
memset(g, , sizeof(g));
tot = -;
memset(du, , sizeof(du));
rt = ;
for (int i = ; i <= m; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
++du[a];
if (du[a] > ) rt = a;
++du[b];
if (du[b] > ) rt = b;
ins(a, b);
ins(b, a);
}
cnt = ;//从根伸出去的链+环的数量
memset(col, , sizeof(col));
col[rt] = ;//访问标记
for (int i = g[rt]; i != -; i = r[i].next)
if (col[r[i].adj] == )
{
t0 = r[i].adj;//用于判环
d[cnt].circle = ;//是否在环中
d[cnt].len = ;//此链Or环的长度(可以想成是点的数量)
dfs(r[i].adj);
++cnt;
}
}
清北学堂模拟day6 兔子的更多相关文章
- 清北学堂模拟day6 圆桌游戏
[问题描述] 有一种圆桌游戏是这样进行的:n个人围着圆桌坐成一圈,按顺时针顺序依次标号为1号至n号.对1<i<n的i来说,i号的左边是i+1号,右边是i-1号.1号的右边是n号,n号的左边 ...
- 清北学堂模拟day6 花
[问题描述] 商店里出售n种不同品种的花.为了装饰桌面,你打算买m支花回家.你觉得放两支一样的花很难看,因此每种品种的花最多买1支.求总共有几种不同的买花的方案?答案可能很大,输出答案mod p的值. ...
- 清北学堂模拟赛day7 数字碰撞
/* clj:水题别人都满分你不是你就完了,所以说水题一定要细心一点,有这么几个细节:①前导零的处理,全是零的时候要特判②换行要注意,不要多大一行,剩下就是水水的模拟了 */ #include< ...
- 清北学堂模拟赛d4t1 a
分析:大模拟,没什么好说的.我在考场上犯了一个超级低级的错误:while (scanf("%s",s + 1)),导致了死循环,血的教训啊,以后要记住了. /* 1.没有发生改变, ...
- 清北学堂模拟赛day7 错排问题
/* 考虑一下已经放回m本书的情况,已经有书的格子不要管他,考虑没有书的格子,不考虑错排有(n-m)!种,在逐步考虑有放回原来位置的情况,已经放出去和已经被占好的格子,不用考虑,剩下全都考虑,设t=x ...
- 清北学堂模拟赛day7 石子合并加强版
/* 注意到合并三堆需要枚举两个端点,其实可以开一个数组记录合并两堆的结果,标程好像用了一个神奇的优化 */ #include<iostream> #include<cstdio&g ...
- 清北学堂模拟day4 捡金币
[问题描述]小空正在玩一个叫做捡金币的游戏.游戏在一个被划分成 n行 n列的网格状场地中进行.每一个格子中都放着若干金币,并且金币的数量会随着时间而不断变化. 小空的任务就是在网格中移动,拾取尽量多的 ...
- 清北学堂模拟day4 传球接力
[问题描述]n 个小朋友在玩传球. 小朋友们用 1 到 n 的正整数编号. 每个小朋友有一个固定的传球对象,第 i 个小朋友在接到球后会将球传给第 ai个小朋友, 并且第 i 个小朋友与第 ai个小朋 ...
- 清北学堂模拟day4 业务办理
[问题描述]在银行柜台前,有 n 个顾客排队办理业务. 队伍中从前往后,第 i 位顾客办理业务需要ti 分钟时间. 一位顾客的等待时间定义为:队伍中在他之前的所有顾客和他自己的办理业务时间的总和.第 ...
随机推荐
- 根据html容器大小和显示文字多少调节字体大小
在做html相关的东西的时候经常会遇到这样的问题,容器大小(长x宽)固定,容器包含内容(特指文字)多少不固定,这个时候就让人很苦恼了,将字体大小设置成多少才合适呢?下面看看我的解决思路: 首先要知道网 ...
- maven仓库没有的包依赖
如果有个jar包是我们自己打的,怎么放到maven中呢? 首先在项目里面新建一个lib目录,如果有lib目录则不需要新建,然后放自己的jar包进去,maven的pom.xml配置是: <depe ...
- HDU 1022 Train Problem I(栈模拟)
传送门 Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot of st ...
- oracle创建用户、表空间、授权
1.打开sqlplus 2.建表空间.用户.授权
- 使用XmlSerializer序列化可空属性
使用XmlSerializer可以方便的将对象序列化为xml,实现应用之间的数据交互.但是XmlSerializer却不能很好地序列化类型中的可空字段. 例如,有如下定义的类Person: [Seri ...
- linux中配置NTP基本操作
计算机的系统时间是由计算机内的石英晶体震荡电路以固定的震荡频率产生的date 查看当前时区vim /etc/sysconfig/clock 修改时区配置文件ZONE="America/Ne ...
- SSH(Struts Spring Hibernate开发框架)
Spring(Model) Spring的核心思想是IoC和AOP,Spring使得管理对象更加方便,极大的降低组件之间的耦合度,实现了软件各层之间的解耦. Struts(View) 使用Struts ...
- python学习笔记-(六)深copy&浅copy
在python中,对象赋值实际上是对象的引用.当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用. 1. 赋值 赋值其实只是传递对象引用,引用对象 ...
- C#------如何判断输入的是否为纯数字
private void Btn_OK_Click(object sender, EventArgs e) { IDormitoryAdminCardService aservice = new Do ...
- Oracle11g的exp导出空表提示EXP-00011: 不存在
刚lg问我11g无法导出空表,实验了下,果真如此. 原因:11g默认创建一个表时不分配segment,只有在插入数据时才会产生(当然也可以强制分配),以节省磁盘空间. 对于已经存在的空表解决办法: 就 ...