luogu P4654 [CEOI2017]Mousetrap
这里把终点设为根方便后续处理,那么目标就是要让老鼠走到根
首先考虑老鼠动不了的情况,这种情况下可以把从这个点到终点路径上的分支堵住,然后再疏通路径上的走过的边,可以发现这是这种情况下最优的决策.在这种情况下,老鼠一定是先往上走一段距离(也可能不走),然后走进某个分支的子树,再被赶到终点.
答案显然满足二分性.对于老鼠,如果有一种策略使得花费步数\(>mid\)那么\(mid\)就不合法.所以可以从起点\(start\)往上走,每到一个点看有没有分支满足这个条件.所以还要知道进入一个子树后的花费步数,记为\(f_x\),转移的话,首先应该把\(f\)最大的儿子堵住,然后老鼠走进次大的儿子,剩下的儿子在老鼠被困住时堵住就行了,所以\(f_x=|son\ of\ x|-[|son\ of\ x|>1]+f_{x2}(son\ of\ x=\{x1,x2,...\},f_{x1}>f_{x2}>f_{x3}...)+1\).
如果进入某个分支子树,那么首先对于当前点,要把其他分支堵住,然后要把祖先的分支也堵住,所以再记分支数量\(s_x=\sum_{y\ is\ the\ ancestor\ of\ x,y\neq root} |son\ of\ y|-[y!=start]\),以及走入某个点以后到结束的操作步数\(g_x=f_x+s_{fa_x}-1\).走到某个点,如果有\(g_x>mid\)的儿子,就要尽量消耗能用的操作次数堵住,这个能用次数初始为\(1\),每次往上走一个点就\(+1\).如果还有这样的\(g_x\)就不合法.要注意每次向上走之前要把\(mid\)减去当前层的使用过的操作次数
// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int N=1e6+10;
LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],tot=1;
void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int n,rt,fa[N],sz[N],f[N],g[N],ans;
int st[N],tp;
void dfs(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x,dfs(y);
}
tp=0;
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
st[++tp]=f[y];
}
sz[x]=tp;
sort(st+1,st+tp+1);
f[x]+=tp-(tp>1)+st[tp-1]+1;
}
bool ck(int mid,int xx)
{
int cn=1,la=0,dt=0;
while(xx!=rt)
{
st[tp=0]=sz[fa[xx]];
for(int i=hd[xx];i;i=nt[i])
{
int y=to[i];
if(y==fa[xx]||y==la) continue;
st[++tp]=g[y];
}
st[0]+=tp;
sort(st+1,st+tp+1);
while(tp>0&&cn>0&&st[tp]>mid) --tp,--cn,++dt;
if(st[tp]>mid) return 0;
mid-=dt,dt=0,la=xx,xx=fa[xx],++cn;
}
return 1;
}
int main()
{
n=rd(),rt=rd();
int x=rd(),la=0;
for(int i=1;i<n;++i) add(rd(),rd());
dfs(rt);
tp=0;
int xx=x;
while(xx!=rt) st[++tp]=xx,xx=fa[xx];
--sz[st[tp]];
for(int i=tp-1;i;--i) sz[st[i]]+=sz[st[i+1]]-1;
++sz[st[1]];
sz[rt]=0;
xx=x;
while(xx!=rt)
{
for(int i=hd[xx];i;i=nt[i])
{
int y=to[i];
if(y==fa[xx]||y==la) continue;
g[y]=f[y]+sz[xx]-1;
}
la=xx,xx=fa[xx];
}
int l=0,r=n;
while(l<=r)
{
int mid=(l+r)>>1;
if(ck(mid,x)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
return 0;
}
luogu P4654 [CEOI2017]Mousetrap的更多相关文章
- [CEOI2017]Mousetrap
P4654 [CEOI2017]Mousetrap 博弈论既视感 身临其境感受耗子和管理的心理历程. 以陷阱为根考虑.就要把耗子赶到根部. 首先一定有解. 作为耗子,为了拖延时间,必然会找到一个子树往 ...
- LOJ2482 CEOI2017 Mousetrap 二分答案、树形DP
传送门 表示想不到二分答案qwq 将树看作以陷阱为根.先考虑陷阱和起始点相邻的情况,此时老鼠一定会往下走,而如果管理者此时不做操作,那么一定会选择让操作次数变得最大的一棵子树.设\(f_i\)表示当前 ...
- Solution -「CEOI 2017」「洛谷 P4654」Mousetrap
\(\mathscr{Description}\) Link. 在一个含 \(n\) 个结点的树形迷宫中,迷宫管理者菈米莉丝和一只老鼠博弈.老鼠初始时在结点 \(y\),有且仅有结点 \(x\ ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- [luogu P2170] 选学霸(并查集+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2170 题目描述 老师想从N名学生中选M人当学霸,但有K对人实力相当,如果实力相当的人中,一部分被选上,另一 ...
- [luogu P2647] 最大收益(贪心+dp)
题目传送门:https://www.luogu.org/problem/show?pid=2647 题目描述 现在你面前有n个物品,编号分别为1,2,3,--,n.你可以在这当中任意选择任意多个物品. ...
- Mousetrap - Keyboard shortcuts in Javascript
Mousetrap is a simple library for handling keyboard shortcuts in Javascript. It is around 2kb minifi ...
- Luogu 考前模拟Round. 1
A.情书 题目:http://www.luogu.org/problem/show?pid=2264 赛中:sb题,直接暴力匹配就行了,注意一下读入和最后一句话的分句 赛后:卧槽 怎么只有40 B.小 ...
随机推荐
- phoenix-hbase 使用
建表命令 CREATE TABLE IF NOT EXISTS "person_mul"( "ROW" varchar primary key, //主键,必须 ...
- 理解PyTorch的自动微分机制
参考Getting Started with PyTorch Part 1: Understanding how Automatic Differentiation works 非常好的文章,讲解的非 ...
- Springboot 项目中引入WebSocket后,单元测试出现错误
报错信息 java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test. ...
- JMH基准测试框架
jmh-gradle-plugin, 集成JMH基准测试框架和 Gradle 0 赞 0 评论 文章标签:Gradle JMH 基准 INT benchmark framework 帧 ...
- JS利用XMLHttpRequest拦截ajax请求
function XMLHttpRequestBreak(fun=()=>false){ let f = XMLHttpRequest.prototype.open; let add = fun ...
- Running .sh scripts in Git bash
Running .sh scripts in Git bash Let's say you have a script script.sh. To run it (using Git Bash), y ...
- Linux高级调试与优化——ptrace
ptrace (process trace) #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_ ...
- 万变的Web,不变的CRUD
用JSP+Servlet写程序,到Struts,Spring,hibernate写程序,到现在Spring Cloud分布式写程序,到底有多大区别,是不是还在写CRUD? 看着JD上各种要求,简直是S ...
- python异常处理--try except else raise finally
转载自https://www.cnblogs.com/bokeyuan11/p/9146607.html 写程序时遇到异常情况,程序可能无法正常运行.此时就需要引入异常处理 1.try ...exce ...
- hdu5747 Aaronson 贪心
Aaronson Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...