Description

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

Solution

为什么我一眼想到最小割=w=
就是所有的逃犯无法到达一些点,那么我们把每个点拆点,x向x’连容量为1的边,割掉这条边表示在这个点放置警卫。
然后对于原图中的每一条边(x,y),从x’向y连容量为∞的边,表示这条边无法被割掉。
同理从S向每个有逃犯的x’点连容量为∞的边,因为无法在有逃犯的点放置警卫。
然后从每个出口的x’点向T连容量为∞的边,因为可以在出口放置警卫。
然后跑一边最小割就是答案了。如果最小割为∞就是无解。
200000个点的最大流什么的真是梦想_ (:зゝ∠)_
然而它碾过去了2333

好吧我们来讨论正解=w=
随便选一个度数为1的点做根节点,那么所有的出口都是根节点或者叶子节点了。
考虑从下往上递推,每个点可以有三种情况
0:这个点为根的子树中所有的逃犯都无法到达这个点,且不存在一条从这点到叶子节点的路径。
1:这个点为根的子树中所有的逃犯都无法到达这个点,但存在一条从这点到叶子节点的路径。
2:这个点为根的子树中所有的逃犯有可能到达这个点,且不存在一条从这点到叶子节点的路径。
那么考虑一个点,如果它的所有儿子都被封死了(就是状态0),那么它自己也就被封死了。
如果这个点有逃犯,那么这个点一下的1点都必须被封死,要不然逃犯可以通过这个点到叶子节点,所以答案加上当前节点状态为1的儿子个数。
否则如果当前点既有状态为1的儿子,又有状态为2的儿子,那么2的逃犯就可以到达这个点,然后从这个点往下逃走。
所以这个点必须被封死。
否则就是只有0\1,0\2的情况,那么除0外是几这个点的状态就是几。
最后如果根节点的状态为2根节点也要封死。

Code

最小割

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=last[a];i;i=next[i])
using namespace std;
const int N=2*1e5+5,inf=1e5;
int n,m,S,T,l,x,y,ans,dis[N],d[N],r[N];
int t[N*8],next[N*8],f[N*8],last[N];
void add(int x,int y,int z) {t[++l]=y;f[l]=z;next[l]=last[x];last[x]=l;t[++l]=x;f[l]=0;next[l]=last[y];last[y]=l;
}
bool bfs() {memset(dis,0,sizeof(dis));dis[S]=1;int i=0,j=1;d[1]=S;while (i<j) rep(k,d[++i]) if (!dis[t[k]]&&f[k]) dis[t[k]]=dis[d[i]]+1,d[++j]=t[k];return dis[T];
}
int dinic(int x,int y) {if (x==T) return y;int now=0;rep(i,x) if (f[i]&&dis[t[i]]==dis[x]+1) {int k=dinic(t[i],min(y,f[i]));y-=k;now+=k;f[i]-=k;f[i^1]+=k;if (!y) break;}if (!now) dis[x]=-1;return now;
}
int main() {scanf("%d%d",&n,&m);n++;S=0;T=2*n+1;l=1;fo(i,1,n-1) {scanf("%d%d",&x,&y);x++;y++;add(x+n,y,inf);add(y+n,x,inf);r[x]++;r[y]++;}fo(i,1,m) scanf("%d",&x),x++,add(S,x+n,inf);fo(i,1,n) if (r[i]==1) add(i+n,T,inf);fo(i,1,n) add(i,i+n,1);while (bfs()) ans+=dinic(S,inf);if (ans>=inf) printf("-1\n");else printf("%d\n",ans);
}

Dp

#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define rep(i,a) for(int i=last[a];i;i=next[i])
using namespace std;
const int N=1e5+5;
int n,m,l,x,y,ans,d[N],f[N];
int t[N*2],next[N*2],last[N];
bool bz[N];
void add(int x,int y) {t[++l]=y;next[l]=last[x];last[x]=l;
}
void dfs(int x,int y) {int s[3];memset(s,0,sizeof(s));rep(i,x) if (t[i]!=y) {dfs(t[i],x);s[f[t[i]]]++;}if (bz[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() {scanf("%d%d",&n,&m);n++;fo(i,1,n-1) {scanf("%d%d",&x,&y),x++,y++;add(x,y),add(y,x);d[x]++;d[y]++;}fo(i,1,n) f[i]=1;fo(i,1,m) {scanf("%d",&x),x++;if (d[x]==1) {printf("-1\n");return 0;}bz[x]=1;}fo(i,1,n) if (d[i]==1) {dfs(i,0);if (f[i]==2) ans++;break;}printf("%d\n",ans);
}

[51nod1299]监狱逃离相关推荐

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

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

  2. 51nod1299 监狱逃离 最小割

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

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

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

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

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

  5. 【51nod1299】监狱逃离(树形DP)

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

  6. 监狱逃离 51nod1299 最小割

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

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

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

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

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

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

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

最新文章

  1. ubuntu 12.04 添加 IP并配置DNS
  2. 如何在一台电脑上同时启动多个tomcat,及如何解决tomcat一闪而过
  3. 服务器json文件怎么创建对象,JavaScript中对JSON对象的基本操作示例
  4. 第四届泉水文化论坛协调会-商协社团:平台经济谋定水产业
  5. Linux 下比较文件内容并相同部分、不同部分
  6. 合并工具_分享一个SM to HISM合并工具
  7. python: 判断字符串是否为合法的json格式
  8. apple tv 开发_如何跨多台Apple TV同步Apple TV的主屏幕
  9. 【渝粤教育】国家开放大学2018年春季 0177-22T电机学(二) 参考试题
  10. mysql order by 索引名字_MySQL如何利用索引优化ORDER BY排序语句
  11. 【Zookeeper】zookeeper客户端KeeperErrorCode = ConnectionLoss
  12. [题解]NOI 2001 食物链
  13. Docker入门之四搭建私有仓库
  14. Commons IO 2.5-IOUtils
  15. 使用移远EC200N-CN模组PING谷歌
  16. 2019-数学建模美赛-B题翻译
  17. 利用webmagic爬去招聘信息,并输入到Hbase数据库中
  18. 数据恢复国赛经验与方法分享(电子产品芯片级检测维修与数据恢复赛项)
  19. Graph U-Nets 笔记
  20. KMP算法的时间复杂度

热门文章

  1. YOLO V6系列(一) -- 跑通YOLO V6算法
  2. 机器学习的所有资源链接和经验教训(五)ML技术讲座
  3. Elasticsearch的安装,以及Springboot整合Elasticsearch
  4. Win10系统设置炫酷下拉关机(其实很简单啦!)
  5. skt7850鸿蒙策略,SKT九连跪,牛肉面
  6. 云联惠认证时间_警方要求云联惠涉案成员限期投案,是自首寻求轻判的最佳时机...
  7. String为什么要用equals而不用==?
  8. matlab单位采样序列程序,常用序列的MATLAB代码(一)
  9. 镜头之滤光片---关于日夜两用双通滤光片
  10. MAC电脑存储空间占用过高怎么办?