传送门

引入两个概念:

最小点权覆盖集:满足每一条边的两个端点至少选一个的最小权点集。

最大点权独立集:满足每一条边的两个端点最多选一个的最大权点集。

现在对网格染色,使得相邻两点颜色不同,之后把两个颜色的点分成两个集合X,Y。S向X集合每个点连一条该点权值的边,Y集合每个点向T连一条该点权值的边,原来的边流量全部变为INF。这个网络的最小割为最小点权覆盖集。因为这个最小割满足了,对于中间每一条边,两端的点必定选择了一个。若一个都没有选择则S与T仍连通。且因为中间的边流量为INF所以不会是中间被堵塞。

然后我们可以证明对于每一个点权覆盖集,将选的点不选,不选的点选,得到的点集一定是一个点权独立集。因为每一条边至少选了一个,反选后就至少有一个选不了。

所以该网络的最小割=最大流=权值和-答案

答案就是权值和-最大流,跑一遍最大流即可

——代码

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #define INF 1e9
  6 #define N 10010
  7 #define M 50001
  8 #define min(x, y) ((x) < (y) ? (x) : (y))
  9
 10 int n, m, cnt, sum, s, t, num;
 11 int head[N], to[M], val[M], next[M], dis[N], cur[N];
 12 int map[101][101], dx[4] = {0, 1, -1, 0}, dy[4] = {1, 0, 0, -1};
 13
 14 inline int read()
 15 {
 16     int x = 0, f = 1;
 17     char ch = getchar();
 18     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
 19     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
 20     return x * f;
 21 }
 22
 23 inline void add(int x, int y, int z)
 24 {
 25     to[cnt] = y;
 26     val[cnt] = z;
 27     next[cnt] = head[x];
 28     head[x] = cnt++;
 29 }
 30
 31 inline bool bfs()
 32 {
 33     int i, u, v;
 34     std::queue <int> q;
 35     memset(dis, -1, sizeof(dis));
 36     q.push(s);
 37     dis[s] = 0;
 38     while(!q.empty())
 39     {
 40         u = q.front(), q.pop();
 41         for(i = head[u]; i ^ -1; i = next[i])
 42         {
 43             v = to[i];
 44             if(val[i] && dis[v] == -1)
 45             {
 46                 dis[v] = dis[u] + 1;
 47                 if(v == t) return 1;
 48                 q.push(v);
 49             }
 50         }
 51     }
 52     return 0;
 53 }
 54
 55 inline int dfs(int u, int maxflow)
 56 {
 57     if(u == t) return maxflow;
 58     int v, d, ret = 0;
 59     for(int &i = cur[u]; i ^ -1; i = next[i])
 60     {
 61         v = to[i];
 62         if(val[i] && dis[v] == dis[u] + 1)
 63         {
 64             d = dfs(v, min(val[i], maxflow - ret));
 65             ret += d;
 66             val[i] -= d;
 67             val[i ^ 1] += d;
 68             if(ret == maxflow) return ret;
 69         }
 70     }
 71     if(ret ^ maxflow) dis[u] = -1;
 72     return ret;
 73 }
 74
 75 int main()
 76 {
 77     int i, j, k, x, y;
 78     m = read();
 79     n = read();
 80     s = 0, t = n * m + 1;
 81     memset(head, -1, sizeof(head));
 82     for(i = 1; i <= m; i++)
 83         for(j = 1; j <= n; j++)
 84         {
 85             num++;
 86             sum += x = read();
 87             if((i + j) & 1)
 88             {
 89                 add(s, num, x), add(num, s, 0);
 90                 if(i > 1) add(num, num - n, INF), add(num - n, num, 0);
 91                 if(i < m) add(num, num + n, INF), add(num + n, num, 0);
 92                 if(j > 1) add(num, num - 1, INF), add(num - 1, num, 0);
 93                 if(j < n) add(num, num + 1, INF), add(num + 1, num, 0);
 94             }
 95             else add(num, t, x), add(t, num, 0);
 96         }
 97     while(bfs())
 98     {
 99         for(i = s; i <= t; i++) cur[i] = head[i];
100         sum -= dfs(s, INF);
101     }
102     printf("%d\n", sum);
103     return 0;
104 }

View Code

转载于:https://www.cnblogs.com/zhenghaotian/p/6936100.html

[luoguP2774] 方格取数问题(最大点权独立集)相关推荐

  1. hdu 1569 方格取数(2) 最大点权独立集

    二分图. 最大点权独立集=总权-最小点权覆盖集. 哪位大神能给一些二分图 最大点权独立集等等 的相关资料!!!!!跪谢 用网络流求解最小点权覆盖集即可,建图不讲了. #include<cstdi ...

  2. hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)...

    转载:http://blog.csdn.net/cold__v__moon/article/details/7924269 /* 这道题和方格取数2相似,是在方格取数2的基础上的变形.方格取数2解法: ...

  3. [网络流][最大点权独立集] 方格取数

    预备知识: 点覆盖集:无向图G的一个点集,使得该图中所有边都至少有一个端点在该集合内. 最小点权覆盖集:在带点权无向图G中,点权之和最小的覆盖集. 点独立集:无向图G的一个点集,使得任两个在该集合中的 ...

  4. 734. [网络流24题] 方格取数问题 二分图点权最大独立集/最小割/最大流

    «问题描述: 在一个有m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任 意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法. «编程任务: 对于给定 ...

  5. BZOJ 1324: Exca王者之剑/BZOJ 1475: 方格取数 最大权独立集 最小割

    1324: Exca王者之剑 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 618  Solved: 310 [Submit][Status][Di ...

  6. [学习笔记]最小割之最小点权覆盖最大点权独立集

    最小点权覆盖 给出一个二分图,每个点有一个非负点权 要求选出一些点构成一个覆盖,问点权最小是多少 建模: S到左部点,容量为点权 右部点到T,容量为点权 左部点到右部点的边,容量inf 求最小割即可. ...

  7. 【网络流24题】I、 方格取数问题(二分图的最大独立集/最小割)

    I. 方格取数问题(二分图的最大独立集/最小割) [问题分析] 二分图点权最大独立集,转化为最小割模型,从而用最大流解决. [建模方法] 首先把棋盘黑白染色,使相邻格子颜色不同,所有黑色格子看做二分图 ...

  8. [codevs 1907] 方格取数3

    [codevs 1907] 方格取数3 题解: 二分图染色.最大点权独立集. 因为要用到最大独立集的一些思路,故先写了一篇最大独立集的题解:http://blog.csdn.net/qq_211102 ...

  9. 线性规划与网络流24题●09方格取数问题13星际转移问题

    ●(做codevs1908时,发现测试数据也涵盖了1907,想要一并做了,但因为"技术"不佳,搞了一上午) ●09方格取数问题(codevs1907  方格取数3) 想了半天,也没 ...

最新文章

  1. 实现一个包含Microsoft.Advertising和SmartMad广告控件的UserControl
  2. 计算两个日期相差几年几个月
  3. python中name没有定义_Python;NameError:未定义名称“handsum”
  4. 判断一个Checkbox是否被选中
  5. 计算机网络之数据链路层:19、总结
  6. 算法高级(33)-拓扑排序-maven依赖关系的确定
  7. uva10668二分解方程
  8. PKM2 - PKManager (基于内容的个人知识管理工具) 5M 绿色免费
  9. 完整JAVAweb项目源码,打字游戏,用jdbc在mysql保存游戏数据,完整项目源码和数据库
  10. java 记住密码的实现_javaweb实现记住密码功能
  11. 我的NVIDIA开发者之旅——优化显卡性能
  12. matlab第三章笔记
  13. 影响ae渲染时间的计算机配置,分享两套影视后期电脑配置2019 能流畅使用ae和pr的电脑主机推荐...
  14. analy32.xll下载_Android Studio 4.0添加了Motion Editor和Build Analyzer
  15. 鼠标点击按钮相应两次
  16. 张粤磊:从杂牌野战军到王牌正规军的蜕变
  17. 小熊派BearPi-HM nano开发板 -- 前期准备
  18. MySQL-18全文本搜索-必知必会
  19. MATLAB产生数字调制基带信号(python对比)
  20. 内核proc参数注释(kernel、vm、net、fs四类)

热门文章

  1. mysql date类型计算_MySQL date类型
  2. php微信网页授权登录代码,php微信网页授权代码(获取用户信息)
  3. 【算法竞赛学习】二手车交易价格预测-Task3特征工程
  4. 程序调用mysql突然变慢_排查Mysql突然变慢
  5. 蓝桥杯--算法入门级题目及答案解析
  6. alexnet 结构_AlexNet的体系结构和实现
  7. 程序员发展应该尽早明白13个道理
  8. 芝麻信用分750以上有什么特殊作用?
  9. 他曾经负债2.5亿,如今身价超过500亿
  10. 一个人到底申请几张信用卡最合适?