题外话:

这是制杖yd的交流题目

题面

首先把捕鼠夹所在的点提出来当根,然后这变成了一棵有根树,我们先来看耗子移动的影响

可以发现耗子往下走就回不来了,而且最后还会被困在一个叶子上,那么这个时候我们把那个子树到根的路径砍成一条链(显然不砍成链耗子可以半路跑进岔路里,至少要你再清理一次,肯定不如砍了优)再把耗子放出来就可以了。而耗子往上走我们是管不了的(指不能阻止它往上走,但是可以砍旁边的分叉,一会具体说),毕竟我们不能把树砍断了,那耗子就到不了夹子了

那么耗子的决策就明确了,它往上走一段之后或者直接找到一个子树钻进去,这个子树应该是我们把子树的根到树的根砍成链需要操作次数最多的,而我们和耗子的博弈就是尽量阻止它钻进需要次数多的子树里。现在考虑求耗子钻进一个点的子树之后我们的最少操作数:先定义$intr[i]$表示耗子钻进$i$我们砍完边再把它放回$i$所需的最小次数,这样方便转移,转移的话因为我们每次只能砍一条边,就是一个点儿子里$intr$的不严格次大值(最大值被我们砍了,如果没有次大值就是零)加上这个点的度数(这个点也需要砍光)再减$1$(这个点和父亲之间的边)。

注意这时的状态还不是到根的答案,要求到根的答案我们还要处理一个$road[i]$表示从$i$到根路径上的岔路。这里我们把耗子所在的初始点到根的链拎出来,然后扫一遍就可以求出来$road$,这样每个点到根的时间就是$intr[i]+road[fa[i]]+(fa[i]==start)$,$+(fa[i]==start)$是因为初始这个点往下走的那条边也要擦一次 。然后我们发现直接求并不好求,因为并不容易知道耗子到底要怎么跑,但是我们可以二分一个答案,然后检验耗子能不能跑进一个超过当前时间的子树即可

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int p[N],noww[*N],goal[*N],path[N],deg[N];
int intr[N],road[N],tort[N],far[N],dep[N];
//intr(into-tree):进入这个点的子树又回来的最小次数
//road:这个点到根路径上的岔路的数目
//tort(to-root):这个点到根的最小操作次数
int n,m,l,r,t1,t2,trp,rat,cnt,mid,ans,ops;
void Link(int f,int t)
{
noww[++cnt]=p[f],p[f]=cnt;
goal[cnt]=t,deg[t]++;
}
void DFS(int nde,int fth,int dth)
{
int max1=,max2=,tmp=-;
far[nde]=fth,dep[nde]=dth;
for(int i=p[nde];i;i=noww[i])
if(goal[i]!=fth)
{
DFS(goal[i],nde,dth+),tmp=intr[goal[i]];
if(tmp>=max1) max2=max1,max1=intr[goal[i]];
else if(tmp>max2) max2=tmp;
}
if(~tmp) intr[nde]=max2+deg[nde]-;//次小值更新intr,叶子节点的是0
if(nde==rat)
{
while(far[nde])
path[++m]=nde,nde=far[nde];//把耗子初始位置到根的链拎出来
for(int i=m,lst=;i;i--,lst=nde)
nde=path[i],road[nde]=road[lst]+deg[nde]-;//扫一遍把岔路数量求出来
}
}
bool check(int x)
{
int lst=;
for(int i=;i<=m;i++)
{
int nde=path[i],tmp=;
for(int j=p[nde];j;j=noww[j])
if(goal[j]!=far[nde]&&goal[j]!=lst)
tmp+=(road[nde]+intr[goal[j]]+(i==)>x);
//这里+(i==1)是说初始这个点往下走的一步也需要擦掉,而它上面的点因为耗子走上来的时候已经把那条边给堵住了就不用擦了
x-=tmp,ops+=tmp,lst=nde;
if(x<||ops>dep[rat]-dep[nde]+) return false;//注意透支次数也是不行的
}
return true;
}
int main()
{
scanf("%d%d%d",&n,&trp,&rat);
for(int i=;i<n;i++)
{
scanf("%d%d",&t1,&t2);
Link(t1,t2),Link(t2,t1);
}
DFS(trp,,),l=,r=;
while(l<=r)
{
mid=(l+r)/,ops=;
if(check(mid)) r=mid-,ans=mid;
else l=mid+;
}
printf("%d",ans);
return ;
}

解题:CEOI 2017 Mousetrap的更多相关文章

  1. Solution -「CEOI 2017」「洛谷 P4654」Mousetrap

    \(\mathscr{Description}\)   Link.   在一个含 \(n\) 个结点的树形迷宫中,迷宫管理者菈米莉丝和一只老鼠博弈.老鼠初始时在结点 \(y\),有且仅有结点 \(x\ ...

  2. 2019.3.16 noiac的原题模拟赛

    RT,这太谔谔了,我不承认这是模拟赛 但是虽然是搬了三道题,题目本身也还能看,就这么着吧 (怎么机房里就我一道原题都没做过啊 T1 CF24D Broken Robot 比较简单地列出式子之后,我们发 ...

  3. 【DTOJ】2704:数字互换

    DTOJ 2704:数字互换  解题报告 2017.11.11 第一版 ——由翱翔的逗比w原创 题目信息: 题目描述 输入两个数作为交换数,输出已交换顺序后的两个值. 输入 两个整数,空格隔开 输出 ...

  4. 【DTOJ】2703:两个数的余数和商

    DTOJ 2703:两个数的余数和商  解题报告 2017.11.10 第一版 ——由翱翔的逗比w原创,引用<C++ Primer Plus(第6版)中文版> 题目信息: 题目描述 给你a ...

  5. 【DTOJ】1001:长方形周长和面积

    DTOJ 1001:长方形周长和面积  解题报告 2017.11.05 第一版  ——由翱翔的逗比w原创 题目信息: 题目描述 已知长方形的长和宽,求长方形的周长和面积? 输入 一行:空格隔开的两个整 ...

  6. 计算机电子书 2018 BiliDrive 备份

    下载方式 根据你的操作系统下载不同的 BiliDrive 二进制. 执行: bilidrive download <link> 链接 文档 链接 Webpack 中文指南.epub (40 ...

  7. 2017.11.11 B201 练习题思路及解题方法

    2017.11.11 B201 练习题思路及解题方法 题目类型及涵盖知识点 本次总共有6道题目,都属于MISC分类的题目,涵盖的知识点有 信息隐藏 暴力破解 音轨,摩斯电码 gif修改,base64原 ...

  8. ACM-ICPC 2017 Asia HongKong 解题报告

    ACM-ICPC 2017 Asia HongKong 解题报告 任意门:https://nanti.jisuanke.com/?kw=ACM-ICPC%202017%20Asia%20HongKon ...

  9. 2017年第六届数学中国数学建模国际赛(小美赛)C题解题思路

    这篇文章主要是介绍下C题的解题思路,首先我们对这道C题进行一个整体的概括,结构如下: C题:经济类 第一问:发现危险人群. 发现:欺诈的方式开始.雇佣或浪漫的承诺. 数据→确定特定的经济萧条地区→确定 ...

随机推荐

  1. Python20-Day04

    ##########迭代器.生成器和面向过程编程########## 一.迭代器 迭代器是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值: l = [1,2,3] cou ...

  2. Sqlserver 每日订单半小时数据统计

    ) '订单数' FROM (SELECT CASE THEN ), create_at, ) ),DATEPART(hh, create_at))+':00:00') ELSE ), create_a ...

  3. TIME_WAIT 你好!

    [root@vm-10-124-66-212 ~]# netstat -an|awk -F ' ' '{print $NF}'|sort |uniq -c |sort -rn|more 5552 TI ...

  4. Notes of Daily Scrum Meeting(11.14)

    Notes of Daily Scrum Meeting(11.14) 今天是项目第三周的周五,按原计划这时我们的项目应该已经要进入尾声进行组装调试了,但由于之前放假还有队员们的 效率比较低的原因,我 ...

  5. Daily Scrum 11.19 部分测试报告

    下面是我们的部分测试报告: 功能测试部分: 1Exception in thread "Thread-11" java.lang.IllegalArgumentException: ...

  6. 除了C语言,C++······竟然还有Z语言?

    只能说自己见识短,头一次听说Z语言.先普及一下吧: Z语言是由牛津大学程序设计研究小组开发的一种形式语言,它是一种以一阶谓词演算为主要理论基础的规约语言,是一种功能性语言.Z语言是将事物的状态和行为用 ...

  7. 由RS-232串口到PROFIBUS-DP总线的转换接口设计

    转自:http://gongkong.ofweek.com/2013-08/ART-310007-11001-28716256_2.html 1.PROFIBUS-DP网络协议 PROFIBUS的网络 ...

  8. windows版本 rac 报错信息

    原因 - 安装程序无法在一个或多个节点上执行指定的脚本.这可能是由于在节点上执行脚本时出现异常错误. 操作 - 有关详细信息, 请查看日志文件 'C:\Users\ADMINI~1\AppData\L ...

  9. [转贴]Linux的SUID SGID 等知识内容

    作者:sparkdev 出处:http://www.cnblogs.com/sparkdev/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接, ...

  10. SpringBoot(六)_AOP统一处理请求

    什么是AOP AOP 是一种编程范式,与编程语言无关: 将通用逻辑从业务逻辑中分离出来(假如你的业务是一条线,我们不在业务线上写一行代码就能完成附加任务!我们会把代码写在其他的地方): 具体实现 (1 ...