51nod 1299 监狱逃离 树形dp
2017-10-30 10:52
260 查看
题意
监狱有N条道路连接N + 1个交点,编号0至N,整个监狱被这些道路连在一起(任何2点之间都有道路),人们通过道路在交点之间走来走去。其中的一些交点只有一条路连接,这些点是监狱的出口。在各个交点中有M个点住着犯人(M <= N + 1),剩下的点可以安排警卫,有警卫把守的地方犯人无法通过。给出整个监狱的道路情况,以及犯人所在的位置,问至少需要安排多少个警卫,才能保证没有1个犯人能够逃到出口,如果总有犯人能够逃出去,输出-1。1<= N <= 100000
分析
据说直接上最小割可以艹过去。。。找一个非叶节点当根,就可以树形dp。
设f[x,0]表示以x为根的树,有犯人走上来且没有到出口的道路。
f[x,1]表示以x为根的树,没有犯人可以走上来且没有到出口的道路。
f[x,2]表示以x为根的树,没有犯人可以走上来且有到出口的道路。
随便转移一下即可。
注意叶节点也犯人点要分类讨论一下。
代码
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int N=100005; const int inf=10000000; int n,m,d ,f [3],last ,cnt,gui ; struct edge{int to,next;}e[N*2]; int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void addedge(int u,int v) { e[++cnt].to=v;e[cnt].next=last[u];last[u]=cnt; e[++cnt].to=u;e[cnt].next=last[v];last[v]=cnt; } void dfs(int x,int fa) { for (int i=last[x];i;i=e[i].next) { if (e[i].to==fa) continue; dfs(e[i].to,x); } if (gui[x]) { for (int i=last[x];i;i=e[i].next) { if (e[i].to==fa) continue; f[x][0]+=min(f[e[i].to][0],f[e[i].to][1]); } f[x][1]=f[x][2]=inf; } else if (d[x]==1) f[x][0]=f[x][1]=1,f[x][2]=0; else { int s1=0,s2=1; for (int i=last[x];i;i=e[i].next) { if (e[i].to==fa) continue; f[x][0]+=min(f[e[i].to][0],f[e[i].to][1]); s1+=f[e[i].to][1];s2+=min(f[e[i].to][0],min(f[e[i].to][1],f[e[i].to][2])); f[x][2]+=min(f[e[i].to][1],f[e[i].to][2]); } f[x][1]=min(s1,s2);f[x][0]=min(f[x][0],s2);f[x][2]=min(f[x][2],s2); } } int main() { n=read()+1;m=read(); for (int i=1;i<n;i++) { int x=read()+1,y=read()+1; addedge(x,y);d[x]++;d[y]++; } while (m--) {int x=read()+1;gui[x]=1;} for (int i=1;i<=n;i++) if (d[i]==1&&gui[i]) {puts("-1");return 0;} int root=0; for (int i=1;i<=n;i++) if (d[i]>1) {root=i;break;} dfs(root,0); printf("%d",min(f[root][0],min(f[root][1],f[root][2]))); return 0; }
相关文章推荐
- 51nod 1299 监狱逃离 树形dp/最小割
- 51nod 1299 监狱逃离
- 51nod 1299 监狱逃离 树形DP
- 51nod-1299 监狱逃离(贪心)
- 51nod 1299 监狱逃离
- 51Nod-1299-监狱逃离
- 51nod 1405 树的距离之和【树形dp】
- 51nod 1405 树的距离之和 【dfs--记忆dp??树形dp??】
- 51NOD-1405 树的距离之和(树形DP)
- 51nod 1405 树的距离之和 (两次dfs,树形dp)
- 【树形DP】51Nod 1500 苹果曼和树
- 51Nod - 1677 树形dp + 组合数学
- 51nod 1378 夹克老爷的愤怒(树形DP+贪心)
- 51Nod-1412-AVL树的种类(树形dp)
- 51Nod 1405 树的距离之和(树形dp)
- 51nod 1737 配对 【树形dp】
- 51nod 1500 苹果曼和树(树形dp)
- 51nod 1405 树的距离之和 树形dp
- 51nod 1378 夹克老爷的愤怒(树形dp)
- 51nod 1378 夹克老爷的愤怒[贪心][树形dp?]