点此看题面

大致题意: 在一棵树中有NNN条边连接N+1N+1N+1个节点,现在已知这棵树上的MMM个节点,要求封住最少的节点,使这MMM个节点中的任意一个节点无法到达叶子节点,若能办到输出最少封住的节点数,若不能输出−1-1−1。

这道题目的正解是树形DPDPDP(hl666hl666hl666大佬说用O(n2m)O(n^2m)O(n2m)的最小割也可以过这道题,不过这篇博客并不讨论这种做法,他能做出来是因为他是常数之神)。

树形DPDPDP,一般都将状态由子节点向父节点转移,这题当然也不例外。

我们可以用fff数组来存储每一个节点的状态:

若f[i]=0f[i]=0f[i]=0,则说明该节点已被完全封死,相当于既不可能有犯人到达这里,也不可能从这里到达出口

若f[i]=1f[i]=1f[i]=1,则说明可以从这个节点到达叶子节点

若f[i]=2f[i]=2f[i]=2,则说明有犯人可以到达该节点

每一次转移,我们可以用一个s[]数组来统计当前节点的子节点中f[son[i]]f[son[i]]f[son[i]]分别为0,1,20,1,20,1,2的次数,并依次进行分类讨论

当前节点有犯人,则需要在该节点的子节点中的每个可以到达叶子节点的节点上安排一个警卫。且f[x]=2f[x]=2f[x]=2(当前节点上有犯人,所以犯人可以到达该节点)。

既有犯人可以到达该节点的某个子节点又可以通过该节点的某个子节点到达叶子节点,这说明有犯人可以通过该节点逃出监狱,则需在这个节点安排一个警卫。且f[x]=0f[x]=0f[x]=0(当前节点安排了警卫,所以被完全封死)。

否则,如果该节点的某个子节点可以到达叶子节点,则说明该节点也可以到达叶子节点,因此f[x]=1f[x]=1f[x]=1。

否则,如果有犯人可以到达该节点的某个子节点,则说明犯人也可以到达该节点,因此f[x]=2f[x]=2f[x]=2。

如果以上情况皆不满足,这说明该节点是叶节点或其子节点全被封死,则特判其为叶子节点的情况,若其不是叶子节点则f[x]=0f[x]=0f[x]=0。

既然这样,就很容易进行动态规划了,具体代码如下:


代码

#include<bits/stdc++.h>
#define N 100000
using namespace std;
int n,m,ee=0,ans,a[N+5]={0},lnk[N+5]={0},OUT[N+5]={0},f[N+5]={0};
struct edge
{int to,nxt;
}e[2*N+5];
inline char tc()
{static char ff[100000],*A=ff,*B=ff;return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{x=0;int f=1;char ch;while(!isdigit(ch=tc())) if(ch=='-') f=-1;while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));x*=f;
}
inline void write(int x)
{if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');
}
inline void add(int x,int y)
{e[++ee]=(edge){y,lnk[x]},lnk[x]=ee,++OUT[x];
}
inline void dp(int x,int lst)//具体的DP过程
{int s[3];s[0]=s[1]=s[2]=0;//用s[]数组来统计当前节点子节点中各种状态的次数register int i;for(i=lnk[x];i;i=e[i].nxt) if(e[i].to^lst) dp(e[i].to,x),++s[f[e[i].to]];//先将其子节点进行DP,是一个递归的过程//接下来是分类讨论的过程if(a[x]) ans+=s[1],f[x]=2;//若当前节点有犯人else if(s[1]&&s[2]) ans++,f[x]=0;//若当前节点既能到达,又能出去else if(s[1]) f[x]=1;//若当前节点能出去else if(s[2]) f[x]=2;//若当前节点能到达else if(s[0]) f[x]=0;//若以上情况皆不满足且该节点不是叶节点
}
int main()
{register int i;int x,y,fst=-1;for(read(n),read(m),i=1;i<=n;++i) read(x),read(y),add(x,y),add(y,x);for(i=1;i<=m;++i) {read(x),a[x]=1;if(OUT[x]==1) return puts("-1"),0;//若有叶子节点关押犯人,则该犯人能直接逃脱}for(i=1;i<=n;++i) if(!(OUT[i]^1)) (fst==-1?fst=i:0),f[i]=1;//将叶子节点的状态初始化为1  dp(fst,0);//从一个叶子节点开始DPreturn write(f[fst]==2?ans+1:ans),0;//特判该节点为2,即犯人可以到达的情况,由于当前节点是叶子节点,所以要在当前节点在安排一个警卫,答案加1
}

【51nod1299】监狱逃离(树形DP)相关推荐

  1. [51nod1299]监狱逃离 树形DP || 20w个点的网络流最小割ORZ

    监狱有N条道路连接N + 1个交点,编号0至N,整个监狱被这些道路连在一起(任何2点之间都有道路),人们通过道路在交点之间走来走去.其中的一些交点只有一条路连接,这些点是监狱的出口.在各个交点中有M个 ...

  2. 51nod 1299 监狱逃离 树形dp

    题意 监狱有N条道路连接N + 1个交点,编号0至N,整个监狱被这些道路连在一起(任何2点之间都有道路),人们通过道路在交点之间走来走去.其中的一些交点只有一条路连接,这些点是监狱的出口.在各个交点中 ...

  3. 51nod 1299 监狱逃离 树形DP

    传送门:51nod 1299 题意:中文题. 思路: //dp[i]表示警察全部放置完成后i节点的状态  //0 表示逃犯不能到达i节点并且i节点能(经由其子树)到达出口(不经过警察的情况下) //1 ...

  4. 51nod 1299 监狱逃离 树形dp/最小割

    题意:监狱有N条道路连接N + 1个交点,编号0至N,整个监狱被这些道路连在一起(任何2点之间都有道路),人们通过道路在交点之间走来走去.其中的一些交点只有一条路连接,这些点是监狱的出口.在各个交点中 ...

  5. 51nod1299 监狱逃离 最小割

    Description 监狱有N条道路连接N + 1个交点,编号0至N,整个监狱被这些道路连在一起(任何2点之间都有道路),人们通过道路在交点之间走来走去.其中的一些交点只有一条路连接,这些点是监狱的 ...

  6. 51nod-1299 监狱逃离(贪心)

    1299 监狱逃离 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题  收藏  关注 监狱有N条道路连接N + 1个交点,编号0至N, ...

  7. [51nod1299]监狱逃离

    Description 给出一个n+1个点n条边的树,其中每一个度数为1的点为出口. 现在有一些点有逃犯,你需要在一些没有逃犯的点放置警卫,有警卫的点逃犯无法经过. 求若使所有逃犯均无法到达出口,最少 ...

  8. [51nod1299] 监狱逃离(最小点覆盖)

    题目链接:https://www.51nod.com/contest/problem.html#!problemId=1299 题意:中文题面. 挺容易想到最小点覆盖的,这么想题目的意思就是希望找到几 ...

  9. 监狱逃离 51nod1299 最小割

    题目大意 监狱有N条道路连接N + 1个交点,编号0至N,整个监狱被这些道路连在一起(任何2点之间都有道路),人们通过道路在交点之间走来走去.其中的一些交点只有一条路连接,这些点是监狱的出口.在各个交 ...

  10. BNUOJ 52305 Around the World 树形dp

    题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52305 Around the World Time Limit: 20000msMemory ...

最新文章

  1. IDEA常用快捷键整理
  2. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解 | 必须收藏!
  3. Java中instanceof用法
  4. 最小熵原理:“物以类聚”之从图书馆到词向量
  5. Android studio 如何查看当前git 分支的4种方式
  6. CentOs基础操作指令(用户管理、组管理)
  7. 登录或连接MYSLQ 提示 error 1045 access denied for user 'root@127.0.0.1' 错误
  8. C语言指针类型 强制转换
  9. 工业控制系统(ICS)
  10. vue项目中使用词云_如何在vue项目中使用高拍仪
  11. 仿射变换再次秒杀2011山东理科高考压轴题(圆锥曲线)
  12. 总结AUTOCAD快捷键,持续更新~
  13. vs2019新手怎么解决命名空间“”中不存在类型或命名空间名“”(是否缺少程序集引用?)问题全解
  14. Docker 命令基础及进阶
  15. SQL 审核查询平台
  16. ime with the \acknowledge=true\ parameter:,watcher:[Watcher will be disabled
  17. 入门行人重识别 尝试跑(郑哲东 简单行人重识别代码到88%准确率)过程
  18. cad捕捉不到标注线上的点_CAD捕捉不到正在绘制的多段线上的点怎么办
  19. java监听器详解_java之监听器详解
  20. 微信小程序云开发学习笔记

热门文章

  1. educoder头歌Web实训 web课——综合应用案例:动态焦点图页面的制作
  2. 带你玩转区块链--以太坊基础、发币、基于智能合约实现彩票项目-第二章-第一节【以太坊篇】
  3. 网易云音乐再成功融资!2018年成数字音乐资本大年
  4. php 获取必应图片信息,PHP自动获取必应今日美图
  5. 《统计建模与R软件》第二章课后作业解题答案
  6. mac book pro 全新安装 windows系统 进行键盘映射,启动标准F1,F2
  7. 计算机高逼格术语,你能看懂这些高逼格专业词汇吗?
  8. Jupyter notebook显示k线图集合
  9. cv2.VideoCapture(0)
  10. java的map是什么_java中的map是什么