题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1565

题意:植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性:(1)价值;(2)保护集合,也就是这个植物可以保护矩阵中的某些格子。现在你是僵尸,你每次只能从(i,m) 格子进入,从右向左进攻。若一个格子是被保护的那么你是不能进入的。每进入一个格子则吃掉该格子的植物并得到其价值(价值有可能是负的)。注意,每次在进 入一行后还可以再退到最右侧然后再换一行吃别的。问最大价值是多少?

思路:(1)首先,我们说下啥是最大权闭合 图。在一个有向图中,每个点集有一个权值。要求选择一个点集使得权值最大。选出的点满足,对于任何一条边<u,v>,若选择了u则必须选择 v。满足这个条件的顶点集叫做最大权闭合子图。在下图中,最大的权闭合子图为{3,4,5},价值为4。

(2)如何求最大权闭合子图?构图方法:增
加原点s和汇点t。原图中的权值x大于0的点,连边<s,i,x>,权值为负的点连边<i,t,-x>。原图中的边权值INF。
上图改造后得到的是下面的图。设新图中与s相连的点的权值和为sum,新图的最小割即最大流为w,则答案为sum-w。下图的sum=12,w=8。

(3)最大权闭合图强调的是点之间的依赖关
系,即选择某个点必须选择另外某些点。在本题中,恰有这样的性质。比如,僵尸必须从右向左,因此,选择左侧的点,就必须选择右侧的点;某个格子被另外的一
些格子保护,那么要选择这个格子,必须要先选择另外的那些格子。我们正好可以用这个性质建立图进行求解。另外,在本题中有可能存在环,即比如同一行右侧的
点被左侧的点保护,那么是无法吃掉这些位置的植物的。因此,首先拓扑排序一次,标记哪些格子不在环中。那么只有这些点是可以到达的。

  1. struct node
  2. {
  3. int v,next,cap;
  4. };
  5.  
  6. node edges[N*100];
  7. int head[N],e;
  8. int pre[N],curedge[N],h[N],num[N];
  9. int s,t;
  10.  
  11. void add(int u,int v,int cap)
  12. {
  13. edges[e].v=v;
  14. edges[e].cap=cap;
  15. edges[e].next=head[u];
  16. head[u]=e++;
  17. }
  18.  
  19. void Add(int u,int v,int cap)
  20. {
  21. add(u,v,cap);
  22. add(v,u,0);
  23. }
  24.  
  25. int visit[N];
  26.  
  27. int Maxflow(int s,int t,int n)
  28. {
  29. clr(h,0); clr(num,0);
  30. int i;
  31. FOR0(i,n+1) curedge[i]=head[i];
  32. int u=s,Min,k,x,ans=0;
  33. while(h[u]<n)
  34. {
  35. if(u==t)
  36. {
  37. Min=INF+1;
  38. for(i=s;i!=t;i=edges[curedge[i]].v)
  39. {
  40. x=curedge[i];
  41. if(edges[x].cap<Min)
  42. {
  43. Min=edges[x].cap;
  44. k=i;
  45. }
  46. }
  47. ans+=Min; u=k;
  48. for(i=s;i!=t;i=edges[curedge[i]].v)
  49. {
  50. x=curedge[i];
  51. edges[x].cap-=Min;
  52. edges[x^1].cap+=Min;
  53. }
  54. }
  55. for(i=curedge[u];i!=-1;i=edges[i].next)
  56. {
  57. if(edges[i].cap>0&&h[u]==h[edges[i].v]+1)
  58. {
  59. break;
  60. }
  61. }
  62. if(i!=-1)
  63. {
  64. curedge[u]=i;
  65. pre[edges[i].v]=u;
  66. u=edges[i].v;
  67. }
  68. else
  69. {
  70. if(--num[h[u]]==0) break;
  71. curedge[u]=head[u];
  72. x=n;
  73. for(i=head[u];i!=-1;i=edges[i].next)
  74. {
  75. k=edges[i].v;
  76. if(edges[i].cap>0&&h[k]<x) x=h[k];
  77. }
  78. h[u]=x+1; num[x+1]++;
  79. if(u!=s) u=pre[u];
  80. }
  81. }
  82. return ans;
  83. }
  84.  
  85. int a[55][55],n,m;
  86. vector<int> g[N];
  87. int d[N],p[N],sum;
  88.  
  89. void build()
  90. {
  91. sum=0; s=0; t=n*m+1; clr(head,-1); e=0;
  92. int i,j,x;
  93. FOR1(i,n*m) if(visit[i]) FOR0(j,SZ(g[i]))
  94. {
  95. x=g[i][j];
  96. if(visit[x]) Add(x,i,INF);
  97. }
  98. FOR1(i,n*m) if(visit[i])
  99. {
  100. if(p[i]>0) Add(s,i,p[i]),sum+=p[i];
  101. if(p[i]<0) Add(i,t,-p[i]);
  102. }
  103. }
  104.  
  105. int main()
  106. {
  107. RD(n,m);
  108. int i,j;
  109. FOR1(i,n) FOR1(j,m) a[i][j]=(i-1)*m+j;
  110. FOR1(i,n)
  111. {
  112. FOR1(j,m-1)
  113. {
  114. g[a[i][j+1]].pb(a[i][j]);
  115. d[a[i][j]]++;
  116. }
  117. }
  118. int x,r,c;
  119. FOR1(i,n) FOR1(j,m)
  120. {
  121. RD(x); p[a[i][j]]=x;
  122. RD(x);
  123. while(x--)
  124. {
  125. RD(r,c); r++; c++;
  126. g[a[i][j]].pb(a[r][c]);
  127. d[a[r][c]]++;
  128. }
  129. }
  130. queue<int> Q;
  131. FOR1(i,n*m) if(!d[i]) Q.push(i);
  132. while(!Q.empty())
  133. {
  134. x=Q.front();
  135. Q.pop();
  136.  
  137. visit[x]=1;
  138. FOR0(i,SZ(g[x]))
  139. {
  140. c=g[x][i];
  141. if(--d[c]==0) Q.push(c);
  142. }
  143. }
  144. build();
  145. PR(sum-Maxflow(s,t,t+1));
  146. }

BZOJ 1565 植物大战僵尸(最大权闭合图)的更多相关文章

  1. BZOJ 1565 植物大战僵尸 最大权闭合子图+网络流

    题意: 植物大战僵尸,一个n*m的格子,每 个格子里有一个植物,每个植物有两个属性: (1)价值: (2)保护集合,也就是这个植物可以保护矩阵中的某些格子. 现在你是僵尸,你每次只能从(i,m) 格子 ...

  2. Bzoj 1565: [NOI2009]植物大战僵尸 最大权闭合图,拓扑排序

    题目: http://cojs.tk/cogs/problem/problem.php?pid=410 410. [NOI2009] 植物大战僵尸 ★★★   输入文件:pvz.in   输出文件:p ...

  3. tyvj P1135 - 植物大战僵尸 最大权闭合图

    P1135 - 植物大战僵尸 From ytt    Normal (OI)总时限:10s    内存限制:128MB    代码长度限制:64KB 背景 Background 虽然这么多天了,,虽然 ...

  4. BZOJ 1565 / P2805 [NOI2009]植物大战僵尸 (最大权闭合子图 最小割)

    题意 自己看吧 BZOJ传送门 分析 - 这道题其实就是一些点,存在一些二元限制条件,即如果要选uuu则必须选vvv.求得到的权值最大是多少. 建一个图,如果选uuu必须选vvv,则uuu向vvv连边 ...

  5. BZOJ 1565 植物大战僵尸(拓扑排序+最大权闭合子图)

    图中的保护关系就类似于最大权闭合子图.即你想杀x,你就一定要杀掉保护x的点,那么把x向保护它的点连边.那么题目就转化成了最大权闭合子图的问题. 但是这个图有点特殊啊... 考虑有环的情况,显然这个环以 ...

  6. bzoj1565: [NOI2009]植物大战僵尸 最大权闭合子图,tarjan

    bzoj1565: [NOI2009]植物大战僵尸 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1565 思路 很容易的想到最大权闭合子图 ...

  7. BZOJ1565[NOI2009]植物大战僵尸——最大权闭合子图+拓扑排序

    题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plants防守,而Zombies进攻.该款游戏包含多 ...

  8. P2805 [NOI2009]植物大战僵尸 + 最大权闭合子图 X 拓扑排序

    传送门:https://www.luogu.org/problemnew/show/P2805 题意 有一个n * m的地图,你可以操纵僵尸从地图的右边向左边走,走的一些地方是有能量值的,有些地方会被 ...

  9. BZOJ_1565_[NOI2009]_植物大战僵尸_(Tarjan+最大流+最大权闭合图)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1565 n*m的矩阵,可以种植植物,僵尸从图的右边进入吃植物.前面的植物可以保护后面的植物,还有 ...

随机推荐

  1. 【NOIP模拟赛】正方形大阵

    正方形大阵 [问题描述]   [输入格式]   第一行一个正整数n代表询问次数. 接下来n行每行一个不超过八位的小数k代表一组询问. [输出格式]   输出共n行,代表每次询问的答案:如果有无数个交点 ...

  2. javascript 操作dom

    Node往往被翻译为节点,在一个对象(可以简单的理解为是HTML页面中),一个属性name="aaa"可以是一个节点,一个< div id="aaa"&g ...

  3. java concurrency in practice读书笔记---ThreadLocal原理

    ThreadLocal这个类很强大,用处十分广泛,可以解决多线程之间共享变量问题,那么ThreadLocal的原理是什么样呢?源代码最能说明问题! public class ThreadLocal&l ...

  4. 【python cookbook】【字符串与文本】4.文本模式的匹配和查找

    问题:按照特定的文本模式进行匹配或查找 解决方法: 1.简单的文字匹配,只需使用str.find().str.startswith().str.endswith()或类似的函数即可: 2.复杂的匹配, ...

  5. win32 Ui 编程 收集

    ---恢复内容开始--- windows sdk编程系列---- 通用控件 http://www.cnblogs.com/MoreNotepad-plus-plus/articles/3164534. ...

  6. Char、AnsiChar、WideChar、PChar、PAnsiChar、PWideChar 的用法

     varc: Char; {Char 类型的取值范围是: #0..#255, 用十六进制表示是: #$0..#$FF}begin{用十进制方式赋值:}c := #65;ShowMessage(c); ...

  7. ExtJS4.2 根据数据库记录构建树形菜单

    背景:最近用ExtJS4.2做一个系统,需要在前端展示资源菜单,为树形结构,该树形结构是从数据库动态加载的. ExtJS的树形结构大致有两种情况: 1.静态树形结构,此处不多说,看API就能简单明白: ...

  8. IE11无法支持Forms认证,,,也就是无法保存COOKIE

    <authentication mode="Forms"> <forms name="xxxx" loginUrl="login.a ...

  9. 几个常见的Laravel报错及解决方法

    报错:「Can't swap PDO instance while within transaction」 transactions >= 1) {throw new RuntimeExcept ...

  10. 连接无线设备——与Wi-Fi直接连接

    原文链接:http://developer.android.com/intl/zh-CN/training/connect-devices-wirelessly/wifi-direct.html 目录 ...