正题

题目链接:https://www.luogu.com.cn/problem/P6499


题目大意

\(n\)个点的一棵树,开始有一个棋子在根处,开始先手选择一个点封锁,然后后手封锁棋子所在点然后移动一步到一个没有封锁的点,之后轮流进行。

先手不知道后手的移动,求先手有没有方法使得后手\(k\)步以内无法移动。


解题思路

后手无法走回头路所以要走到深度为\(k\)的节点,那么问题就变为了在\(k\)以内的每个深度选择一个节点切断,求能否使得树的深度不到达\(k\)。(显然第\(i\)步肯定是封锁深度为\(i\)的更优,因为如果选小于的后手已经跨过这个深度,选大的不如选它的父节点)。

然后n,k是400所以考虑状压dp。有一个结论就是如果\(n\leq k^2\)那么一定有解,因为如果\(n\leq k^2\)那么对于每个深度我们可以每次选择一个分叉的节点,然后去掉条路径一个没有分叉的边,这样每一次至少减少\(2k-1\)条边,然后深度(就是\(k\))减一,若干次以后就是\(k^2\)了。

这样就能把\(k\)缩到\(\sqrt n\)的复杂度,考虑状压。先在可能封锁的点上跑一个\(dfs\)序,然后设\(f_{i,s}\)表示目前决策到第\(dfn_i\)个点,每个深度被选择的情况为\(s\)是否合法。

然后如果选择一个点就直接跳到\(dfs\)序上该节点的子树末尾\(+1\)。然后强制选叶子就好了。

时间复杂度\(O(n2^{min\{k,\sqrt n\}})\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=410;
struct node{
int to,next;
}a[N<<1];
int n,k,tot,cnt,ls[N],dep[N],dfn[N],ed[N];
bool mark[N],f[N][1<<20];
void addl(int x,int y){
a[++tot].to=y;
a[tot].next=ls[x];
ls[x]=tot;return;
}
bool dfs(int x,int fa){
dep[x]=dep[fa]+1;
if(dep[x]+1==k)return mark[x]=1;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa)continue;
mark[x]|=dfs(y,x);
}
return mark[x];
}
void dfc(int x,int fa){
if(!mark[x])return;dfn[cnt++]=x;
for(int i=ls[x];i;i=a[i].next){
int y=a[i].to;
if(y==fa)continue;
dfc(y,x);
}
ed[x]=cnt;return;
}
int main()
{
scanf("%d%d",&n,&k);
if(n<=k*k)return puts("DA")&0;
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
addl(x,y);addl(y,x);
}
dep[0]=-2;dfs(1,0);dfc(1,0);
int MS=(1<<k);f[1][0]=1;
for(int i=1;i<cnt;i++){
int x=dfn[i];
for(int s=0;s<MS;s++){
if(dep[x]!=k-1)f[i+1][s]|=f[i][s];
if(!((s>>dep[x])&1))
f[ed[x]][s|(1<<dep[x])]|=f[i][s];
}
}
bool ans=0;
for(int s=0;s<MS;s++)
ans|=f[cnt][s];
puts(ans?"DA":"NE");
return 0;
}

最新文章

  1. iOS-数据持久化详细介绍
  2. PHP读写文件
  3. hdfs创建级联文件夹
  4. 从图片加载纹理-使用glut工具
  5. 为 Macbook 安装 enca 命令
  6. linux 修改系统时间
  7. JavaScript/jQuery选择器简介
  8. [svn] 数据库操作残留,无法进行操作的解决方法
  9. button元素兼容问题浅析
  10. vb sqlite 使用 litex
  11. MBG 相关资源链接
  12. assembly打包实例
  13. HDU 4857 逃生(反向拓扑排序+优先队列)
  14. Win10下, TortoiseGit安装及配合Gitee使用完整版
  15. sublime No packages available for installation
  16. Intel汇编指令格式解析
  17. Redux 实现过程的推演
  18. HTML XML 介绍
  19. Spark RDD操作之Map系算子
  20. uWSGI, Gunicorn, 啥玩意儿?

热门文章

  1. 什么是TCP,什么是UDP,它们两者的区别? 三次握手
  2. spring4整合hibernate5以及出现的问题解决办法
  3. Linux中的静态库与动态库
  4. Navicat查询出的数据有时候不能更改?
  5. 统计MySQL数据库硬盘占用量大小
  6. C# 使用正则表达式替换PPT中的文本(附vb.net代码)
  7. opencv入门系列教学(六)图像上的算术运算(加法、融合、按位运算)
  8. com.google.zxing.NotFoundException-识别图片二维码信息错误
  9. IPv4掩码与掩码位数的转换
  10. CSS导航菜单(二级菜单)