[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\),用不到 ...
随机推荐
- Selenium 入门到精通系列:六
Selenium 入门到精通系列 PS:Checkbox方法 例子 HTML: <html> <head> <title>测试页面</title> &l ...
- <cfenv>(fenv.h) _c++11
头文件 <cfenv>(fenv.h) c++11 浮点环境 这个头文件声明了一系列的函数和宏去访问浮点环境,以及特殊的类型. 浮点环境维护一系列的状态标志(status flags)和具 ...
- 【isJson( jsonObj )】判断是否是JSON实例
判断是否是JSON实例: 原型:isJson( jsonObj ) 说明:判断对象是否是JSON实例 返回:[true | false] 示例: <% Set jsonObj1 = toJson ...
- HDU - 6440(费马小定理)
链接:HDU - 6440 题意:重新定义加法和乘法,使得 (m+n)^p = m^p + n^p 成立,p是素数.,且satisfied that there exists an integer q ...
- appium启动APP配置参数:
一.Android启动app python启动脚本如下: from appium import webdriver desired_caps = {} desired_caps['plat ...
- jquery取radio单选按钮
// var strMess = '<%=Exchange() %>';// if (strMess == "兑换成功") {// ...
- HDU 3260/POJ 3827 Facer is learning to swim(DP+搜索)(2009 Asia Ningbo Regional)
Description Facer is addicted to a game called "Tidy is learning to swim". But he finds it ...
- UVALive - 6886 Golf Bot 多项式乘法(FFT)
题目链接: http://acm.hust.edu.cn/vjudge/problem/129724 Golf Bot Time Limit: 15000MS 题意 给你n个数,m个查询,对于每个查询 ...
- lintcode-153-数字组合 II
153-数字组合 II 给出一组候选数字(C)和目标数字(T),找出C中所有的组合,使组合中数字的和为T.C中每个数字在每个组合中只能使用一次. 注意事项 所有的数字(包括目标数字)均为正整数. 元素 ...
- python爬虫--打开爬取页面
def requests_view(response): import webbrowser requests_url = response.url base_url = '<head>& ...