[CEOI2017]Mousetrap
博弈论既视感
身临其境感受耗子和管理的心理历程。
以陷阱为根考虑。就要把耗子赶到根部。
首先一定有解。
作为耗子,为了拖延时间,必然会找到一个子树往下走。
如果耗子从子树往下走的话,
那么一定会走到一个叶子被自己卡住。
作为管理,堵路比清理容易的多。否则耗子进去了还得清理把它轰出来。
所以,耗子进入一个子树,管理先手,必定堵住花费最大的子树,耗子会到次大的子树
然后耗子还要赶回来,赶回来之前,一定先把沿途其他的路堵住,再放耗子回来
所以树形dp
in[x]表示,耗子从以x为根的子树往下走,再回到x共花费的次数
in[x]=cmx(in[y])+du[x]-2+1
cmx表示次大值。度数这一层要堵住的其他路,+1是走下去的这个边还要清理。
耗子回来了,怎么办?
耗子往上走,找机会还会往下。所以综合考虑,不如在耗子困进子树叶子里之后,先把到root的链上所有其他分支堵住,然后再放耗子出来,一定就进了陷阱
cos[x]=in[x]+沿途度数和
但是耗子不一定往下走。可能一开始往上走,再往下走
不好处理,不如二分
沿着链往上走,记录还能行动的次数,以及可以多k次先手(先手有用,省着先不做)
如果一个点管理员瞎玩去了没有干啥,耗子进入最大子树,这样花费已经固定。
考虑花费是否大于剩余的步数
否则用一次先手机会,然后花费一次行动堵住。
如果行动不够,或者先手不够,那么GG
注意堵儿子的时候,之前堵上的就不用再堵了,所以记录tmp为堵住的叶子个数。
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
il void rd(int &x){
char ch;x=;bool fl=false;
while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);
(fl==true)&&(x=-x);
}
namespace Miracle{
const int N=1e6+;
const int inf=0x3f3f3f3f;
struct node{
int nxt,to;
}e[*N];
int hd[N],cnt;
int du[N];
int n,t,m;
int in[N],cos[N],dep[N];
int fa[N];
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
bool cmp(int x,int y){
return cos[x]>cos[y];
}
void dfs(int x,int d,int c){
dep[x]=d;
int cmx=,mx=;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa[x]) continue;
fa[y]=x;
if(x!=t) dfs(y,d+,c+du[x]-);
else dfs(y,d+,c);
if(in[y]>mx){
cmx=mx;mx=in[y];
}else{
cmx=max(cmx,in[y]);
}
}
in[x]=cmx++du[x]-;
cos[x]=in[x]+c+(fa[x]==m);
}
bool che(int mid){//root is t ; start is m
//cout<<" mid "<<mid<<endl;
int re=mid;
int k=;
int now=m;
// if(ch[now].size()){
// if(cos[ch[now][0]]>=re) --re;
// else ++k;
// }
// if(re<0) return false;
// if(k<0) return false;
//cout<<" midmid "<<mid<<" : "<<re<<endl;
int las=;
//now=fa[now];
while(now!=t){
++k;
int tmp=;
for(reg i=hd[now];i;i=e[i].nxt){
int y=e[i].to;
if(y==las||y==fa[now]) continue;
if(cos[y]-tmp>re){
--k;--re;
++tmp;
}
if(re<) return false;
if(k<) return false;
}
las=now;
now=fa[now];
}
return true;
}
int main(){
rd(n);rd(t);rd(m);
if(m==t){
puts("");return ;
}
int x,y;
for(reg i=;i<n;++i){
rd(x);rd(y);
++du[x];++du[y];
add(x,y);add(y,x);
}
dfs(t,,);
// for(reg i=1;i<=n;++i){
// cout<<" ii "<<i<<" : "<<in[i]<<" "<<cos[i]<<endl;
// }
int L=,R=n+;
L=cos[m];
int ans=;
while(L<=R){
int mid=(L+R)>>;
if(che(mid)){
ans=mid;
R=mid-;
}else{
L=mid+;
}
}
printf("%d",ans);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/12/29 10:05:21
*/ /*
Author: *Miracle*
Date: 2018/12/29 10:05:21
*/
总结:
挺不错的小游戏
还是考虑每个角色的策略吧。
有一些分析和直觉猜测。
[CEOI2017]Mousetrap的更多相关文章
- LOJ2482 CEOI2017 Mousetrap 二分答案、树形DP
传送门 表示想不到二分答案qwq 将树看作以陷阱为根.先考虑陷阱和起始点相邻的情况,此时老鼠一定会往下走,而如果管理者此时不做操作,那么一定会选择让操作次数变得最大的一棵子树.设\(f_i\)表示当前 ...
- luogu P4654 [CEOI2017]Mousetrap
传送门 这里把终点设为根方便后续处理,那么目标就是要让老鼠走到根 首先考虑老鼠动不了的情况,这种情况下可以把从这个点到终点路径上的分支堵住,然后再疏通路径上的走过的边,可以发现这是这种情况下最优的决策 ...
- Mousetrap - Keyboard shortcuts in Javascript
Mousetrap is a simple library for handling keyboard shortcuts in Javascript. It is around 2kb minifi ...
- Luogu4655 [CEOI2017]Building Bridges
Luogu4655 [CEOI2017]Building Bridges 有 \(n\) 根柱子依次排列,每根柱子都有一个高度.第 \(i\) 根柱子的高度为 \(h_i\) . 现在想要建造若干座桥 ...
- loj#2483. 「CEOI2017」Building Bridges 斜率优化 cdq分治
loj#2483. 「CEOI2017」Building Bridges 链接 https://loj.ac/problem/2483 思路 \[f[i]=f[j]+(h[i]-h[j])^2+(su ...
- [CEOI2017]Palindromic Partitions
[CEOI2017]Palindromic Partitions 题目大意: 给出一个长度为\(n(n\le10^6)\)的只包含小写字母字符串,要求你将它划分成尽可能多的小块,使得这些小块构成回文串 ...
- [原创]Javascript 利用mousetrap.js进行键盘事件操作
我们日常开发中,会遇到js的键盘操作,例如回车提交表单之类的.或者按下某个键执行某个方法.无意中发现一个大小不到4K的js文件,它非常方便的操作键盘事件. 自己也尝试了一下:具体代码如下: 详情可以去 ...
- ceoi2017 Building Bridges(build)
Building Bridges(build) 题目描述 A wide river has nn pillars of possibly different heights standing out ...
- 题解-[CEOI2017]Building Bridges
[CEOI2017]Building Bridges 有 \(n\) 个桥墩,高 \(h_i\) 重 \(w_i\).连接 \(i\) 和 \(j\) 消耗代价 \((h_i-h_j)^2\),用不到 ...
随机推荐
- 【Python+OpenCV】人脸识别基于环境Windows+Python3 version_3(Anaconda3)+OpenCV3.4.3安装配置最新版安装配置教程
注:本次安装因为我要安装的是win10(64bit)python3.7与OpenCV3.4.3教程(当下最新版,记录下时间2018-11-17),实际中这个教程的方法对于win10,32位又或是64位 ...
- c字符指针与字符数组的区别
1.定义 char *pchar; //定义了指针,没赋值之前不能使用.如果:printf("*pchar:%c\n",*pchar); 出现段错误Segmentation fa ...
- vivado使用感想
寒假学了一学期vivado也没有学出什么名堂:为了调试龙芯的五级流水CPU,今天肝了一下午结果还把vivado给摸清楚了,果然是以目标为导向最能出成绩. vivado开发硬件的流程 写代码 模拟仿真s ...
- Kali渗透测试工具-nslookup
1.交互模式 终端输入nslookup进入交互模式 (1)查询A地址记录(默认) set q=a A记录简单理解将域名转换成对应的IP地址 (2)查询mail exchanger set q=mx m ...
- c#,mysql,读取乱码问题
1.首先保证数据库的表是UTF8类型:数据库是否是utf8无关紧要: 2.c#连接数据库语句添加“charset=utf8”一句:.exe.config是否添加这一句也无关紧要: 3.访问数据库数据用 ...
- 第一周—Fortran语言学习
使用教材:Fortran95程序设计[彭国伦] 第二章 编译器的使用 编译结果的好坏 1.翻译正确 2.执行文件的运行效率 3.翻译出来的执行码的长短 4.编译过程花费的时间 5.编译器提供Debug ...
- Innodb 中 RR 隔离级别能否防止幻读?
问题引出 我之前的一篇博客 数据库并发不一致分析 有提到过事务隔离级别以及相应加锁方式.能够解决的并发问题. 标准情况下,在 RR(Repeatable Read) 隔离级别下能解决不可重复读(当行修 ...
- 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp
题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...
- Shel脚本学习—反引号、单引号、双引号区别与联系
反引号 反引号位 (`) 位于键盘的Tab键的上方.1键的左方.注意与单引号(')位于Enter键的左方的区别. 在Linux中起着命令替换的作用.命令替换是指shell能够将一个命令的标准输出插在一 ...
- BZOJ4804 欧拉心算(莫比乌斯反演+欧拉函数+线性筛)
一通套路后得Σφ(d)μ(D/d)⌊n/D⌋2.显然整除分块,问题在于怎么快速计算φ和μ的狄利克雷卷积.积性函数的卷积还是积性函数,那么线性筛即可.因为μ(pc)=0 (c>=2),所以f(pc ...