题外话:

这是制杖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. 用shell实现bat批处理的pause命令-追加改进

    我参考了这个文章:用shell实现bat的pause http://linux-wiki.cn/wiki/zh-hans/%E7%94%A8shell%E5%AE%9E%E7%8E%B0bat%E7% ...

  2. Tomcat源码学习(3)—— Digester介绍

    Digester方法详解: 通读Digester之前先分析下他的结构: 1.1该类继承了方法DefaultHandler2,DefaultHandler2继承了DefaultHandler是和sax解 ...

  3. uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)"解决办法

    如果在编译MFC程序的时候出现下列及类似的错误: 1>uafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator ...

  4. 为什么使用React Native

    React Native使你能够在Javascript和React的基础上获得完全一致的开发体验,构建世界一流的原生APP. React Native着力于提高多平台开发的开发效率 —— 仅需学习一次 ...

  5. 1、Ansible安装配置

    ansible介绍: Ansible是一款基于Python开发的自动化运维工具,主要是实现批量系统配置.批量程序部署.批量运行命令.批量执行任务等等诸多功能.Ansible是一款灵活的开源工具,能够很 ...

  6. 第十次ScrumMeeting博客

    第十次ScrumMeeting博客 本次会议于11月5日(日)22时整在新主楼G座2楼召开,持续20分钟. 与会人员:刘畅.辛德泰.窦鑫泽.张安澜.赵奕.方科栋. 特邀嘉宾:陈彦吉学长. 1. 每个人 ...

  7. 对React children 的深入理解

    React的核心为组件.你可以像嵌套HTML标签一样嵌套使用这些组件,这使得编写JSX更加容易因为它类似于标记语言. 当我刚开始学习React时,当时我认为“使用 props.children 就这么 ...

  8. 王者荣耀交流协会final发布文案美工展示博客

    logo: 我们的logo是蓝底白字,非常简洁大气的设计感,上面印有我们的软件名称,更好的直观的彰显了我们的主题.我们的软件就是要迎合使用者,给使用者更加方便快捷的工作体验,更好的衡量自己的时间分配. ...

  9. 20172324《Java程序设计》第3周学习总结

    20172324<Java程序设计>第3周学习总结 教材学习内容总结 随机数,记住要返回的是指定的字符前一个. String类型的一些用法,例如concat(连接),toUpperCase ...

  10. 《JavaScript》字符转义

    escape/unescape encodeURIComponent/decodeURIComponent encodeURI/decodeURI 转义函数会对一些 特殊字符进行转义编码 英文.数字. ...