【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1475

【题目大意】

  给出一个n*n的方格,从中取一些不相邻的数字,使得和最大

【题解】

  我们可以根据i+j的奇偶性将点划分为两组,同组之间无连边,因此这是一张二分图
  我们建立源点对偶点引点权大小的流量,建立汇点,从每个奇点引点权大小的流量到汇点,
  总点权减去该图的最小割就是答案,因为最小割中的边表示了该点被选中去除,
  所有去除点和最小,那么剩下的满足限制条件的就一定是最大值了。

【代码】

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <vector>
  4. #include <queue>
  5. using namespace std;
  6. const int INF=0x3f3f3f3f;
  7. const int MAX_V=1000;
  8. struct edge{int to,cap,rev;};
  9. vector<edge> G[MAX_V];
  10. int level[MAX_V],iter[MAX_V];
  11. void add_edge(int from,int to,int cap){
  12. G[from].push_back((edge){to,cap,G[to].size()});
  13. G[to].push_back((edge){from,0,G[from].size()-1});
  14. }
  15. void bfs(int s){
  16. memset(level,-1,sizeof(level));
  17. queue<int> que;
  18. level[s]=0;
  19. que.push(s);
  20. while(!que.empty()){
  21. int v=que.front(); que.pop();
  22. for(int i=0;i<G[v].size();i++){
  23. edge &e=G[v][i];
  24. if(e.cap>0&&level[e.to]<0){
  25. level[e.to]=level[v]+1;
  26. que.push(e.to);
  27. }
  28. }
  29. }
  30. }
  31. int dfs(int v,int t,int f){
  32. if(v==t)return f;
  33. for(int &i=iter[v];i<G[v].size();i++){
  34. edge &e=G[v][i];
  35. if(e.cap>0&&level[v]<level[e.to]){
  36. int d=dfs(e.to,t,min(f,e.cap));
  37. if(d>0){
  38. e.cap-=d;
  39. G[e.to][e.rev].cap+=d;
  40. return d;
  41. }
  42. }
  43. }return 0;
  44. }
  45. int max_flow(int s,int t){
  46. int flow=0;
  47. for(;;){
  48. bfs(s);
  49. if(level[t]<0)return flow;
  50. memset(iter,0,sizeof(iter));
  51. int f;
  52. while((f=dfs(s,t,INF))>0){
  53. flow+=f;
  54. }
  55. }
  56. }
  57. int n,a[30][30];
  58. void solve(){
  59. int sum=0,s=n*n,t=n*n+1;
  60. for(int i=0;i<=t;i++)G[i].clear();
  61. for(int i=0;i<n;i++)for(int j=0;j<n;j++){
  62. if((i+j)%2==0){
  63. if(i+1<n)add_edge(i*n+j,(i+1)*n+j,INF);
  64. if(j+1<n)add_edge(i*n+j,i*n+j+1,INF);
  65. if(i>0)add_edge(i*n+j,(i-1)*n+j,INF);
  66. if(j>0)add_edge(i*n+j,i*n+j-1,INF);
  67. add_edge(s,i*n+j,a[i][j]);
  68. }else add_edge(i*n+j,t,a[i][j]);
  69. sum+=a[i][j];
  70. }printf("%d\n",sum-max_flow(s,t));
  71. }
  72. int main(){
  73. while(~scanf("%d",&n)){
  74. for(int i=0;i<n;i++){
  75. for(int j=0;j<n;j++)scanf("%d",&a[i][j]);
  76. }solve();
  77. }return 0;
  78. }

BZOJ 1475 方格取数(二分图最大点权独立集)的更多相关文章

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

    HDU 1565 1569 方格取数(最大点权独立集) 题目链接 题意:中文题 思路:最大点权独立集 = 总权值 - 最小割 = 总权值 - 最大流 那么原图周围不能连边,那么就能够分成黑白棋盘.源点 ...

  2. hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)

    /** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...

  3. HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]

    嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...

  4. hdu1569 方格取数 求最大点权独立集

    题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和.思路:建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),问题转化为求总权和-最小点权覆盖集(点 ...

  5. TZOJ 3665 方格取数(2)(最大点权独立集)

    描述 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. 输入 包括多个测试实例 ...

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

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 两道题只是数据范围不同,都是求的最大点权独立集. 我们可以把下标之和为奇数的分成一个集合,把下标之和为偶数 ...

  7. BZOJ 1475: 方格取数( 网络流 )

    本来想写道水题....结果调了这么久!就是一个 define 里面少加了个括号 ! 二分图最大点权独立集...黑白染色一下 , 然后建图 : S -> black_node , white_no ...

  8. [BZOJ 1475] 方格取数

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1475 [算法] 首先将方格黑白染色 , 也就是说 , 如果(i + j)为奇数 , ...

  9. SCU3185 Black and white(二分图最大点权独立集)

    题目大概说有几个黑色.白色矩阵,问能选出黑白不相交的矩形面积和的最大值. 建二分图,黑色矩阵为X部的点,白色为Y部,XY的点权都为其矩阵面积,如果有个黑白矩阵相交则它们之间有一条边,那样问题就是要从这 ...

随机推荐

  1. javascript继承机制 & call apply使用说明

    一.继承机制 1.对象冒充:构造函数使用 this 关键字给所有属性和方法赋值,可使 ClassA 构造函数成为 ClassB 的方法,然后调用它. function ClassZ() { this. ...

  2. (Git 钩子)自定义你的工作流 和引用日志

    Git 钩子是在 Git 仓库中特定事件发生时自动运行的脚本.它可以让你自定义 Git 内部的行为,在开发周期中的关键点触发自定义的行为. Git 钩子最常见的使用场景包括推行提交规范,根据仓库状态改 ...

  3. Override 和 Overload 的含义和区别

    Override 1.方法重写.覆盖: 2.重写是父类与子类之间多态性的一种表现: 3.方法名,参数,返回值相同: 4.存在于子类和父类之间: 5.修饰为final的方法,不能被重写: Overloa ...

  4. Linux内核堆栈使用方法 进程0和进程1【转】

    转自:http://blog.csdn.net/yihaolovem/article/details/37119971 目录(?)[-] 8 Linux 系统中堆栈的使用方法 81  初始化阶段 82 ...

  5. Linux内核模块编程可以使用的内核组件

    2.2.2 在阅读<深入Linux内核架构与底层原理> 作者:刘京洋 韩方,发现一些错误,有些自己的理解,特以此记录 1.工作队列(workqueue) 队列是一种可以先进先出的数据结构, ...

  6. 64_d1

    DSDP-5.8-15.fc26.i686.rpm 13-Feb-2017 22:06 658926 DSDP-5.8-15.fc26.x86_64.rpm 13-Feb-2017 22:09 653 ...

  7. sunos kernel src

    https://github.com/eocallaghan/AuroraUX-SunOS https://github.com/zoyanhui/coroutine-libtask https:// ...

  8. 超级rtmp服务器和屌丝wowza

    超级rtmp服务器和屌丝wowza http://blog.csdn.net/win_lin/article/details/11927973

  9. 【bzoj1649】Cow Roller Coaster

    傻逼dp题. dp[i][j]表示用了i长度已花费成本j所能得到的价值. 然后枚举一下铁轨随便做了. 不行就sort一下. #include<bits/stdc++.h> #define ...

  10. Makefile系列之一 : 书写规则

    1. 规则 target : prerequisites command  2. example excute 为最终生成的可执行文件. 可以通过命令 make clean来删除所有编译时产生的中间文 ...