【题意】

  在一个有 m*n 个方格的棋盘中, 每个方格中有一个正整数。 现要从方格中取数, 使任意 2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。

输入文件示例
input.txt
3 3
1 2 3
3 2 3
2 3 1

输出文件示例
output.txt
11

【分析】

  方格的行列之和的奇偶构成二分图,转化成二分图点权最大独立集。

  相邻的建边。

  假设所有点都能取,

  st->u 流量w[u] u的行列和为偶数

  v->ed 流量为w[v]  v的行列和为奇数

  u,v相邻 u->v 流量为INF 表示若u->v 相邻,必定要去掉一个(即割掉与源点或汇点的一条边)

  就是最小割。

  用sum-最小割即为答案。

  二分图点权最大独立集是很经典的模型。

  傻逼的我还没看出来二分图以为会算重复,真是。。。

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<cmath>
  8. using namespace std;
  9. #define Maxn 1010
  10. #define INF 0xfffffff
  11.  
  12. struct node
  13. {
  14. int x,y,f,o,next;
  15. }t[Maxn*];int len;
  16. int first[Maxn];
  17.  
  18. int mymin(int x,int y) {return x<y?x:y;}
  19. int mymax(int x,int y) {return x>y?x:y;}
  20.  
  21. void ins(int x,int y,int f)
  22. {
  23. t[++len].x=x;t[len].y=y;t[len].f=f;
  24. t[len].next=first[x];first[x]=len;t[len].o=len+;
  25. t[++len].x=y;t[len].y=x;t[len].f=;
  26. t[len].next=first[y];first[y]=len;t[len].o=len-;
  27. }
  28.  
  29. int st,ed;
  30. queue<int > q;
  31. int dis[Maxn];
  32. bool bfs()
  33. {
  34. while(!q.empty()) q.pop();
  35. memset(dis,-,sizeof(dis));
  36. q.push(st);dis[st]=;
  37. while(!q.empty())
  38. {
  39. int x=q.front();
  40. for(int i=first[x];i;i=t[i].next) if(t[i].f>)
  41. {
  42. int y=t[i].y;
  43. if(dis[y]==-)
  44. {
  45. dis[y]=dis[x]+;
  46. q.push(y);
  47. }
  48. }
  49. q.pop();
  50. }
  51. if(dis[ed]==-) return ;
  52. return ;
  53. }
  54.  
  55. int ffind(int x,int flow)
  56. {
  57. if(x==ed) return flow;
  58. int now=;
  59. for(int i=first[x];i;i=t[i].next) if(t[i].f>)
  60. {
  61. int y=t[i].y;
  62. if(dis[y]==dis[x]+)
  63. {
  64. int a=ffind(y,mymin(flow-now,t[i].f));
  65. t[i].f-=a;
  66. t[t[i].o].f+=a;
  67. now+=a;
  68. }
  69. if(now==flow) break;
  70. }
  71. if(now==) dis[x]=-;
  72. return now;
  73. }
  74.  
  75. void output()
  76. {
  77. for(int i=;i<=len;i+=)
  78. printf("%d->%d %d\n",t[i].x,t[i].y,t[i].f);
  79. }
  80.  
  81. int max_flow()
  82. {
  83. int ans=;
  84. while(bfs())
  85. {
  86. ans+=ffind(st,INF);
  87. }
  88. return ans;
  89. }
  90.  
  91. int bx[]={,,,,-},
  92. by[]={,,,-,};
  93.  
  94. int main()
  95. {
  96. int n,m,sum=;
  97. scanf("%d%d",&n,&m);
  98. st=n*m+;ed=st+;
  99. for(int i=;i<=n;i++)
  100. for(int j=;j<=m;j++)
  101. {
  102. int x,now=(i-)*m+j;
  103. scanf("%d",&x);
  104. sum+=x;
  105. if((i+j)%==) ins(st,now,x);
  106. else ins(now,ed,x);
  107. }
  108. for(int i=;i<=n;i++)
  109. for(int j=;j<=m;j++)
  110. {
  111. int now=(i-)*m+j;
  112. for(int k=;k<=;k++) if(i+bx[k]>=&&i+bx[k]<=n&&j+by[k]>=&&j+by[k]<=m)
  113. {
  114. int nn=(i+bx[k]-)*m+j+by[k];
  115. if((i+j)%==) ins(now,nn,INF);
  116. else ins(nn,now,INF);
  117. }
  118. }
  119. int x=max_flow();
  120. printf("%d\n",sum-x);
  121. return ;
  122. }

2016-11-04 15:32:42

【网络流24题】No.9 方格取数问题 (二分图点权最大独立集)的更多相关文章

  1. [网络流24题#9] [cogs734] 方格取数 [网络流,最大流最小割]

    将网格分为两部分,方法是黑白染色,即判断(i+j)&1即可,分开后从白色格子向黑色格子连边,每个点需要四条(边界点可能更少),也就是每个格子周围的四个方向.之后将源点和汇点分别于黑白格子连边, ...

  2. luogu2774 方格取数问题 二分图最小权点覆盖集

    题目大意:在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,输出这些数之和的最大值. 思路:这种各个点之间互相排斥求最大值的题,往往需要利 ...

  3. BZOJ 1475 方格取数(二分图最大点权独立集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1475 [题目大意] 给出一个n*n的方格,从中取一些不相邻的数字,使得和最大 [题解] ...

  4. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  5. 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)

      HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...

  6. HDU1569 方格取数(2) —— 二分图点带权最大独立集、最小割最大流

    题目链接:https://vjudge.net/problem/HDU-1569 方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory L ...

  7. 洛谷 - P2774 - 方格取数问题 - 二分图最大独立点集 - 最小割

    https://www.luogu.org/problemnew/show/P2774 把两个相邻的节点连边,这些边就是要方便最小割割断其他边存在的,容量无穷. 这种类似的问题的话,把二分图的一部分( ...

  8. 【Luogu】P2774方格取数问题(最大点权独立集)

    题目链接 不知道为啥坠大点权独立集的做法跟最大权闭合图差不多? qwq 放个链接 #include<cstdio> #include<cstring> #include< ...

  9. [luoguP2774] 方格取数问题(最大点权独立集)

    传送门 引入两个概念: 最小点权覆盖集:满足每一条边的两个端点至少选一个的最小权点集. 最大点权独立集:满足每一条边的两个端点最多选一个的最大权点集. 现在对网格染色,使得相邻两点颜色不同,之后把两个 ...

  10. HDU 1565:方格取数(1)(最大点权独立集)***

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意:中文. 思路:一个棋盘,要使得相邻的点不能同时选,问最大和是多少,这个问题就是最大点权独立集. 可以 ...

随机推荐

  1. C#汉字转拼音首字母

    输入汉字,提取其首字母: /// <summary> /// 汉字转拼音缩写 /// Code By /// 2004-11-30 /// </summary> /// < ...

  2. Top 10 Uses of a Message Queue

    Top 10 Uses of a Message QueueAsynchronicity, Work Dispatch, Load Buffering, Database Offloading, an ...

  3. OS X EL Capitan安装Cocoapods 报错ERROR

    升级OS X EL Capitan10.11之后,原来的pod不能用了,重新安装cocoapods,发现 在运行 “sudo gem install cocoapods” 的时候出现问题: ERROR ...

  4. 安装flash 插件scaleform出现错误:Scaleform Launch Panel.Launcher.handleDataLoaderIOError(): Loading XML Failedscaleform

    经排查发现是Scaleform Launcher.swf报的错 (C:\Users\Administrator\AppData\Local\Adobe\Flash CC\zh_CN\Configura ...

  5. 原型模式(Prototype Pattern)

    原型模型:用于创建重复对象,同时保证性能. 这种模式实现一个原型接口,用于创建对象的克隆,当直接创建对象的代价比较大,则可以采用这种模式.例如:一个对象需要高代价的数据库操作之后被创建,这时可以缓存该 ...

  6. swift基本语法

    swift种语法着实怪异,实质干的事情还是一样的,一下将对此语法做简单介绍: 1.swift语法种已经剔除“:”这个结束符号,下面将演示入门操作的hello world import Foundati ...

  7. 01_安装redhat 7.1时常出现的问题

    1. 笔记本安装时出现"dev/boot does not find ",进不去安装界面. 这是因为pci设备的问题,解决方法:在出现安装选项时,按Tab进入option模式,在末 ...

  8. input多选图片与显示

    input标签 在使用input选择文件时遇到了 在遍历input file.files 只显示最后一个,修改如下: CSS: <style type="text/css"& ...

  9. IE11的CSS兼容性问题

    最近测试给了我一大堆BUG,一瞅发现全是IE11的.吐槽一下这个浏览器真的比较特立独行.很多默认的样式跟别的浏览器不同,而且最明显的一点应该是padding左右内边距往往比别的浏览器大了一倍.但是当需 ...

  10. ES6 语法简介

    参考: http://es6.ruanyifeng.com/ 总结学习 JavaScript语言下一代标准,2015年6月正式发布. 1.let和const命令 let用作变量声明,只在代码块内有效 ...