如果将其转化为一个更一般的问题即二分图带权最小单边点覆盖(最小控制集)感觉是非常npc的。考虑原题给的一大堆东西究竟有什么奇怪的性质。

  容易发现如果与特殊边相邻的两格子都放了方块,并且这两个格子都各有另一个相邻格子放了方块,其组成的连通块就是需要破坏的。自然四个格子都可以选择破坏。可以发现如果在中间的两个格子里选的话,应该选择破坏权值较小的,因为其对其他格子没有影响。同时注意到另两个格子在黑白染色的图中一定是不同色的。

  那么做法就很显然了,建四层点,外部两层是不与特殊边相邻的黑白点,内部两层是与特殊边相邻的黑白点,外部点分别与源汇连边权为其权值的边,内部点之间连边权为较小权值的边,外部点和内部点之间连inf边,跑最小割即可。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<algorithm>
  7. #include<map>
  8. using namespace std;
  9. #define ll long long
  10. #define N 100010
  11. #define S 0
  12. #define T 100001
  13. #define inf 1000000010
  14. char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
  15. int gcd(int n,int m){return m==?n:gcd(m,n%m);}
  16. int read()
  17. {
  18. int x=,f=;char c=getchar();
  19. while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
  20. while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
  21. return x*f;
  22. }
  23. int c,r,n,p[N],t=-;
  24. int d[N],cur[N],q[N],ans;
  25. struct data{int to,nxt,cap,flow;
  26. }edge[N<<];
  27. struct data2{int x,y;
  28. }a[N];
  29. map<int,int> f[N],id[N];
  30. int wx[]={,,,-},wy[]={,,-,};
  31. void addedge(int x,int y,int z)
  32. {
  33. t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].cap=z,edge[t].flow=,p[x]=t;
  34. t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].cap=,edge[t].flow=,p[y]=t;
  35. }
  36. bool isblack(int x,int y){return x+y&;}
  37. bool isnear(int x,int y){return x&?y%==||y%==:y%==||y%==;}
  38. bool bfs()
  39. {
  40. memset(d,,sizeof(d));d[S]=;
  41. int head=,tail=;q[]=S;
  42. do
  43. {
  44. int x=q[++head];
  45. for (int i=p[x];~i;i=edge[i].nxt)
  46. if (d[edge[i].to]==-&&edge[i].flow<edge[i].cap)
  47. {
  48. d[edge[i].to]=d[x]+;
  49. q[++tail]=edge[i].to;
  50. }
  51. }while (head<tail);
  52. return ~d[T];
  53. }
  54. int work(int k,int f)
  55. {
  56. if (k==T) return f;
  57. int used=;
  58. for (int i=cur[k];~i;i=edge[i].nxt)
  59. if (d[k]+==d[edge[i].to])
  60. {
  61. int w=work(edge[i].to,min(f-used,edge[i].cap-edge[i].flow));
  62. edge[i].flow+=w,edge[i^].flow-=w;
  63. if (edge[i].flow<edge[i].cap) cur[k]=i;
  64. used+=w;if (used==f) return f;
  65. }
  66. if (used==) d[k]=-;
  67. return used;
  68. }
  69. void dinic()
  70. {
  71. while (bfs())
  72. {
  73. memcpy(cur,p,sizeof(p));
  74. ans+=work(S,inf);
  75. }
  76. }
  77. int main()
  78. {
  79. #ifndef ONLINE_JUDGE
  80. freopen("bzoj4823.in","r",stdin);
  81. freopen("bzoj4823.out","w",stdout);
  82. const char LL[]="%I64d\n";
  83. #else
  84. const char LL[]="%lld\n";
  85. #endif
  86. c=read(),r=read(),n=read();
  87. memset(p,,sizeof(p));
  88. for (int i=;i<=n;i++)
  89. {
  90. int y=read(),x=read(),z=read();
  91. f[a[i].x=x][a[i].y=y]=z;id[x][y]=i;
  92. }
  93. for (int i=;i<=n;i++)
  94. if (!isnear(a[i].x,a[i].y)&&isblack(a[i].x,a[i].y))
  95. {
  96. addedge(S,i,f[a[i].x][a[i].y]);
  97. for (int j=;j<;j++)
  98. if (isnear(a[i].x+wx[j],a[i].y+wy[j])&&id[a[i].x+wx[j]][a[i].y+wy[j]])
  99. for (int k=;k<;k++)
  100. if (isnear(a[i].x+wx[j]+wx[k],a[i].y+wy[j]+wy[k])&&id[a[i].x+wx[j]+wx[k]][a[i].y+wy[j]+wy[k]])
  101. for (int x=;x<;x++)
  102. {
  103. int u=a[i].x+wx[j]+wx[k]+wx[x],v=a[i].y+wy[j]+wy[k]+wy[x];
  104. if (!isnear(u,v)&&id[u][v]) addedge(i,id[a[i].x+wx[j]][a[i].y+wy[j]],inf),addedge(id[a[i].x+wx[j]+wx[k]][a[i].y+wy[j]+wy[k]],id[u][v],inf);
  105. }
  106. }
  107. for (int i=;i<=n;i++)
  108. if (!isnear(a[i].x,a[i].y)&&!isblack(a[i].x,a[i].y)) addedge(i,T,f[a[i].x][a[i].y]);
  109. for (int i=;i<=n;i++)
  110. if (isnear(a[i].x,a[i].y)&&!isblack(a[i].x,a[i].y))
  111. for (int j=;j<;j++)
  112. if (isnear(a[i].x+wx[j],a[i].y+wy[j])&&id[a[i].x+wx[j]][a[i].y+wy[j]])
  113. addedge(i,id[a[i].x+wx[j]][a[i].y+wy[j]],min(f[a[i].x][a[i].y],f[a[i].x+wx[j]][a[i].y+wy[j]]));
  114. dinic();
  115. cout<<ans;
  116. return ;
  117. }

BZOJ4823 CQOI2017老C的方块(最小割)的更多相关文章

  1. bzoj4823: [Cqoi2017]老C的方块(最小割)

    4823: [Cqoi2017]老C的方块 题目:传送门 题解: 毒瘤题ORZ.... 太菜了看出来是最小割啥边都不会建...狂%大佬强强强   黑白染色?不!是四个色一起染,四层图跑最小割... 很 ...

  2. bzoj 4823: [Cqoi2017]老C的方块 [最小割]

    4823: [Cqoi2017]老C的方块 题意: 鬼畜方块游戏不解释... 有些特殊边,有些四个方块组成的图形,方块有代价,删掉一些方块使得没有图形,最小化代价. 比较明显的最小割,一个图形中必须删 ...

  3. BZOJ4823 [Cqoi2017]老C的方块 【最小割】

    题目 老C是个程序员. 作为一个懒惰的程序员,老C经常在电脑上玩方块游戏消磨时间.游戏被限定在一个由小方格排成的R行C列网格上,如果两个小方格有公共的边,就称它们是相邻的,而且有些相邻的小方格之间的公 ...

  4. [bzoj4823][Cqoi2017]老C的方块

    来自FallDream的博客,未经允许,请勿转载,谢谢. 挺有意思的一道题.... 看完题面比较明确是最小割,考虑怎么建图 想了比较久 突破口应该是题目中那张奇怪的图 观察这个奇怪的图和方块,很容易发 ...

  5. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  6. bzoj 4823 & 洛谷 P3756 老C的方块 —— 最小割

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4823 https://www.luogu.org/problemnew/show/P3756 ...

  7. 【BZOJ4823】[CQOI2017]老C的方块(网络流)

    [BZOJ4823][CQOI2017]老C的方块(网络流) 题面 BZOJ 题解 首先还是给棋盘进行黑白染色,然后对于特殊边左右两侧的格子单独拎出来考虑. 为了和其他格子区分,我们把两侧的这两个格子 ...

  8. 【洛谷P3756】[CQOI2017]老C的方块(最小割)

    洛谷 题意: 给出一个网格图类似于这样: 现在给出一个\(n*m\)大小的网格,之后会给出一些点,若某些点相连形成了如下的几个图案,那么就是不好的. 现在可以删去一些点,但删除每个点都有一些代价,问最 ...

  9. BZOJ 4823 Luogu P3756 [CQOI2017]老C的方块 (网络流、最小割)

    题目链接 (Luogu) https://www.luogu.org/problem/P3756 (BZOJ) http://lydsy.com/JudgeOnline/problem.php?id= ...

随机推荐

  1. 机器学习实战:KNN代码报错“AttributeError: 'dict' object has no attribute 'iteritems'”

    报错代码: sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True) 解决 ...

  2. Java:二进制(原码、反码、补码)与位运算

    一.二进制(原码.反码.补码) 二进制的最高位是符号位(“0”代表正数,“1”代表负数): Java中没有无符号数: 计算机以整数的补码进行运算: 1.  原码:将一个整数转换成二进制表示 以 int ...

  3. JDBC事务机制

    package com.jdbc.test; import java.sql.*; /** * 数据库的引擎必须是innodb */ public class Demo02 { PreparedSta ...

  4. appium -- 页面出现弹窗,关闭后,无法识别页面元素

    1. 问题:如图所示:在修改手势密码的过程中,点击了返回按钮后,弹出该弹窗:点击继续设置后,就发现 driver.getPageSource()获取不到页面元素.在找了一圈无用的资料后,没有什么好的处 ...

  5. Windows10系统,安装appium之坑

    本文主要讲述如何在 Windows10 系统上通过 npm 命令行安装 appium 应该有很多小伙伴在使用cnpm安装appium时遇到过各种报错,比如这样: 相信很多的小伙伴都会遇到这样的报错,导 ...

  6. 给大家推荐:五个Python小项目,Github上的人气很高的

    1.深度学习框架 Pytorch https://github.com/pytorch/pytorch PyTorch 是一个 Torch7 团队开源的 Python 优先的深度学习框架,提供两个高级 ...

  7. MySQL三方面优化

    第一方面:30种mysql优化sql语句查询的方法1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中使用 ...

  8. 《Git学习指南》学习笔记(三)

    多次提交 提交一般分未两步:add和commit. add将修改存入到索引(index)或叫暂存区(staging area)中. status命令 status命令会出现三种可能的状态: chang ...

  9. Java学习 · 初识 面向对象基础一

    面向对象基础 1.1面向过程与面向对象的区别 面向过程和面向对象二者都是思考问题的方式,再简单的事物时,可以线性思考时使用面向过程,但当事物较为复杂时,只能使用面向对象设计.但二者并不是对立的,在解决 ...

  10. Python replace方法并不改变原字符串

    直接给出结论:replace方法不会改变原字符串. temp_str = 'this is a test' print(temp_str.replace('is','IS') print(temp_s ...