洛谷

题意:

给出一个网格图类似于这样:

现在给出一个\(n*m\)大小的网格,之后会给出一些点,若某些点相连形成了如下的几个图案,那么就是不好的。

现在可以删去一些点,但删除每个点都有一些代价,问最终不出现上述图案的最小代价为多少。

思路:

初一看这图是什么乱七八糟的,但仔细观察能够发现它们的共性:对于蓝色的边两旁的格子,我们称为灰点;若有两个灰点相连,并且它们各自至少还连接了一个点,那么就是不合法的图案。

同时观察网格奇偶性,之后对网格奇偶染色。

然后初步思路为:源点连向所有白点,容量为白点权值;黑点向汇点连边,容量也为权值;然后中间为两两相连的灰点,权值为两者最小值。之后求个最小割就行了(相当于不存在一条白-灰-灰-黑的路径)。

但是这还有连边的细节需要分情况讨论一下,假设我们固定白点为起点,那么在不同行,灰点间的连边是不同的。

详见代码吧:

  1. #include <bits/stdc++.h>
  2. #define MP make_pair
  3. #define fi first
  4. #define se second
  5. #define sz(x) (int)(x).size()
  6. #define all(x) (x).begin(), (x).end()
  7. //#define Local
  8. #ifdef Local
  9. #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
  10. void err() { std::cout << '\n'; }
  11. template<typename T, typename...Args>
  12. void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
  13. #else
  14. #define dbg(...)
  15. #endif
  16. void pt() {std::cout << '\n'; }
  17. template<typename T, typename...Args>
  18. void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
  19. using namespace std;
  20. typedef long long ll;
  21. typedef pair<int, int> pii;
  22. //head
  23. const int N = 5e5 + 5;
  24. int c, r, n;
  25. int x[N], y[N], w[N], col[N];
  26. #define INF 0x3f3f3f3f
  27. template <class T>
  28. struct Dinic{
  29. struct Edge{
  30. int v, next;
  31. T flow;
  32. Edge(){}
  33. Edge(int v, int next, T flow) : v(v), next(next), flow(flow) {}
  34. }e[N << 1];
  35. int head[N], tot;
  36. int dep[N];
  37. void init() {
  38. memset(head, -1, sizeof(head)); tot = 0;
  39. }
  40. void adde(int u, int v, T w, T rw = 0) {
  41. e[tot] = Edge(v, head[u], w);
  42. head[u] = tot++;
  43. e[tot] = Edge(u, head[v], rw);
  44. head[v] = tot++;
  45. }
  46. bool BFS(int _S, int _T) {
  47. memset(dep, 0, sizeof(dep));
  48. queue <int> q; q.push(_S); dep[_S] = 1;
  49. while(!q.empty()) {
  50. int u = q.front(); q.pop();
  51. for(int i = head[u]; ~i; i = e[i].next) {
  52. int v = e[i].v;
  53. if(!dep[v] && e[i].flow > 0) {
  54. dep[v] = dep[u] + 1;
  55. q.push(v);
  56. }
  57. }
  58. }
  59. return dep[_T] != 0;
  60. }
  61. T dfs(int _S, int _T, T a) {
  62. T flow = 0, f;
  63. if(_S == _T || a == 0) return a;
  64. for(int i = head[_S]; ~i; i = e[i].next) {
  65. int v = e[i].v;
  66. if(dep[v] != dep[_S] + 1) continue;
  67. f = dfs(v, _T, min(a, e[i].flow));
  68. if(f) {
  69. e[i].flow -= f;
  70. e[i ^ 1].flow += f;
  71. flow += f;
  72. a -= f;
  73. if(a == 0) break;
  74. }
  75. }
  76. if(!flow) dep[_S] = -1;
  77. return flow;
  78. }
  79. T dinic(int _S, int _T) {
  80. T max_flow = 0;
  81. while(BFS(_S, _T)) max_flow += dfs(_S, _T, INF);
  82. return max_flow;
  83. }
  84. };
  85. Dinic <int> solver;
  86. map <int , int> mp[N];
  87. const int dx[] = {1, -1, 0, 0};
  88. const int dy[] = {0, 0, 1, -1};
  89. void run() {
  90. for(int i = 1; i <= n; i++) {
  91. cin >> x[i] >> y[i] >> w[i];
  92. mp[x[i]][y[i]] = i;
  93. if(y[i] % 2 == 0) {
  94. if(x[i] % 4 == 0 || x[i] % 4 == 3) col[i] = 2;
  95. else if((x[i] + y[i]) & 1) col[i] = 1;
  96. else col[i] = 0;
  97. } else {
  98. if(x[i] % 4 == 1 || x[i] % 4 == 2) col[i] = 2;
  99. else if((x[i] + y[i]) & 1) col[i] = 1;
  100. else col[i] = 0;
  101. }
  102. }
  103. solver.init();
  104. dbg(mp[1][1]);
  105. int s = 0, t = n + 1;
  106. for(int i = 1; i <= n; i++) {
  107. if(col[i] == 1) solver.adde(s, i, w[i]);
  108. }
  109. for(int i = 1; i <= n; i++) {
  110. if(col[i] == 0) solver.adde(i, t, w[i]);
  111. }
  112. for(int i = 1; i <= n; i++) {
  113. if(col[i] == 2) continue;
  114. for(int j = 0; j < 4; j++) {
  115. int curx = x[i] + dx[j], cury = y[i] + dy[j];
  116. int id = mp[curx][cury];
  117. if(id > 0 && col[id] == 2) {
  118. if(col[i] == 0) {
  119. solver.adde(id, i, INF);
  120. }
  121. else {
  122. solver.adde(i, id, INF);
  123. }
  124. }
  125. }
  126. }
  127. for(int i = 1; i <= n; i++) {
  128. if(col[i] != 2) continue;
  129. int curx, cury;
  130. if(y[i] % 2) {
  131. curx = x[i] + 1, cury = y[i];
  132. } else {
  133. curx = x[i] - 1, cury = y[i];
  134. }
  135. int id = mp[curx][cury];
  136. if(id > 0 && col[id] == 2) {
  137. solver.adde(i, id, min(w[id], w[i]));
  138. }
  139. }
  140. int ans = solver.dinic(0, t);
  141. cout << ans << '\n';
  142. }
  143. int main() {
  144. ios::sync_with_stdio(false);
  145. cin.tie(0); cout.tie(0);
  146. cout << fixed << setprecision(20);
  147. #ifdef Local
  148. freopen("../input.in", "r", stdin);
  149. freopen("../output.out", "w", stdout);
  150. #endif
  151. while(cin >> c >> r >> n) run();
  152. return 0;
  153. }

【洛谷P3756】[CQOI2017]老C的方块(最小割)的更多相关文章

  1. [bzoj4823][洛谷P3756][Cqoi2017]老C的方块

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

  2. 洛谷$P3756\ [CQOI2017]$老$C$的方块 网络流

    正解:网络流 解题报告: 传送门$QwQ$ 看到不能出现给定的讨厌的图形,简单来说就,特殊边两侧的方格不能同时再连方格. 所以如果出现,就相当于是四种方案?就分别炸四个格子. 然后冷静分析一波之后发现 ...

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

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

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

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

  5. 洛咕 P3756 [CQOI2017]老C的方块

    四染色,贼好想 一个弃疗图形刚好对应一个红-绿-黄-粉色路线(不要吐槽颜色) 就是裸的最小割,建图傻逼懒得写了 #include<bits/stdc++.h> #define il inl ...

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

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

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

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

  8. [bzoj4824][洛谷P3757][Cqoi2017]老C的键盘

    Description 老 C 是个程序员. 作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序 在某种神奇力量的驱使之下跑得非常快.小 Q 也 ...

  9. 洛谷 P3757 [CQOI2017]老C的键盘

    题面 luogu 题解 其实就是一颗二叉树 我们假设左儿子小于根,右儿子大于根 考虑树形\(dp\) \(f[u][i]\)表示以\(u\)为根的子树,\(u\)为第\(i\)小 那么考虑子树合并 其 ...

  10. 洛谷P3757 [CQOI2017]老C的键盘

    传送门 首先可以直接把整个序列建成一个完全二叉树的结构,这个应该都看得出来 然后考虑树形dp,以大于为例 设$f[i][j]$表示$i$这个节点在子树中排名第$j$位时的总方案数(因为实际只与相对大小 ...

随机推荐

  1. (day55)七、查询优化、MTV和MCV、choices、AJAX、序列化

    目录 一.ORM查询优化 (一)only与defer (1)only (2)defer (二)select_related与prefatch_related (1)select_related (2) ...

  2. 使用Python对ElasticSearch获取数据及操作

    #!/usr/bin/env python# -*- coding: utf-8 -*-""" @Time : 2018/7/4 @Author : LiuXueWen ...

  3. DRF--验证器

    前戏 在之前我们对前端妹子传来的数据进行校验,使用的是序列化类来进行校验的,但这里面往往满足不了我们的需求,更多的时候我们希望自己定义校验规则.这里介绍三种自定义校验的方式.分别是单一字段校验,多个字 ...

  4. Unity 2018 Artificial Intelligence Cookbook Second Edition (Jorge Palacios 著)

    https://github.com/PacktPublishing/Unity-2018-Artificial-Intelligence-Cookbook-Second-Edition 1 Beha ...

  5. QMap::remove操作,并不会调用值的析构,跟QTreeWidget同类,需要主动去释放

    void test_MapRemvoe() { DBOperator * painter = new DBOperator; QMap<int , DBOperator*> map; ma ...

  6. ThreadLocal 简单解析

    ThreadLocal 简单解析 基于jdk1.8 ThreadLocal一定不陌生,开发中常用,也是面试里的常客了,但是往往我们可能只是知道该类的作用.学习该类对于个人的多线程编码能力是大有裨益的, ...

  7. awk、sed、grep更适合的方向

    awk.sed.grep更适合的方向: grep 更适合单纯的查找或匹配文本 sed 更适合编辑匹配到的文本 awk 更适合格式化文本,对文本进行较复杂格式处理 关于awk内建变量个人见解,简单易懂 ...

  8. 卡尔曼滤波C++代码

    #include <ros/ros.h> #include <string> #include <stdlib.h> #include <iostream&g ...

  9. oracle like模糊查询不能走索引?

    这里要纠正一个网上很多教程说的模糊匹配不能走索引的说法,因为在看<收获,不止SQL优化>一书,里面举例说到了,并且自己也跟着例子实践了一下,确实like一些特殊情况也是可以走索引的 例子来 ...

  10. html-加水印--watermark--代码测试

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...