题目链接:https://vjudge.net/problem/HDU-1569

方格取数(2)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6876    Accepted Submission(s): 2198

Problem Description
给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
 
Input
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
 
Output
对于每个测试实例,输出可能取得的最大的和
 
Sample Input
3 3
75 15 21
75 15 28
34 70 5
 
Sample Output
188
 
Author
ailyanlu
 
Source

题解:

1.将n*m的格子建模成二分图。

2.在二分图的基础上添加源点S和汇点T, 然后从S向所有X集合中的点连一条边, 所有Y集合中的点向T连一条边, 容量均为该点的权值。

3.X集合的结点与Y集合的结点之间的边的容量为无穷大。在此题中,如果是格子相邻,就需要连边,且是X-->Y。

4.因此,对于该图中的任意一个割, 将割中的边所对应的结点删掉,就是一个符合条件的解,权值和为所有权和减去割的容量。

5.根据4可得:只要求出最小割, 就能求出最大权值和独立集。

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int MAXM = 1e5+;
const int MAXN = +; struct Edge
{
int to, next, cap, flow;
}edge[MAXM];
int tot, head[MAXN];
int gap[MAXN], dep[MAXN], pre[MAXN], cur[MAXN]; void init()
{
tot = ;
memset(head, -, sizeof(head));
} void add(int u, int v, int w)
{
edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = ;
edge[tot].next = head[u]; head[u] = tot++;
edge[tot].to = u; edge[tot].cap = ; edge[tot].flow = ;
edge[tot].next = head[v]; head[v] = tot++;
} int sap(int start, int end, int nodenum)
{
memset(dep, , sizeof(dep));
memset(gap, , sizeof(gap));
memcpy(cur, head, sizeof(head));
int u = pre[start] = start, maxflow = ,aug = INF;
gap[] = nodenum;
while(dep[start]<nodenum)
{
loop:
for(int i = cur[u]; i!=-; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap-edge[i].flow && dep[u]==dep[v]+)
{
aug = min(aug, edge[i].cap-edge[i].flow);
pre[v] = u;
cur[u] = i;
u = v;
if(v==end)
{
maxflow += aug;
for(u = pre[u]; v!=start; v = u,u = pre[u])
{
edge[cur[u]].flow += aug;
edge[cur[u]^].flow -= aug;
}
aug = INF;
}
goto loop;
}
}
int mindis = nodenum;
for(int i = head[u]; i!=-; i = edge[i].next)
{
int v=edge[i].to;
if(edge[i].cap-edge[i].flow && mindis>dep[v])
{
cur[u] = i;
mindis = dep[v];
}
}
if((--gap[dep[u]])==)break;
gap[dep[u]=mindis+]++;
u = pre[u];
}
return maxflow;
} int n, m, g[][];
int main()
{
while(scanf("%d%d", &n, &m)!=EOF)
{
int sum = ;
for(int i = ; i<n; i++)
for(int j = ; j<m; j++)
scanf("%d", &g[i][j]), sum += g[i][j]; int start = n*m, end = n*m+;
init();
for(int i = ; i<n; i++)
for(int j = ; j<m; j++)
{
if((i+j)%)
{
add(start, i*m+j, g[i][j]);
if(i!=) add(i*m+j, (i-)*m+j, INF);
if(i!=n-) add(i*m+j, (i+)*m+j, INF);
if(j!=) add(i*m+j, i*m+j-, INF);
if(j!=m-) add(i*m+j, i*m+j+, INF);
}
else
add(i*m+j, end, g[i][j]);
} sum -= sap(start, end, n*m+);
printf("%d\n", sum);
}
}

HDU1569 方格取数(2) —— 二分图点带权最大独立集、最小割最大流的更多相关文章

  1. HDU1565 方格取数(1) —— 状压DP or 插头DP(轮廓线更新) or 二分图点带权最大独立集(最小割最大流)

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

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

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

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

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

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

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

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

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

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

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

  7. Luogu_2774 方格取数问题

    Luogu_2774 方格取数问题 二分图最小割 第一次做这种题,对于某些强烈暗示性的条件并没有理解到. 也就是每一立刻理解到是这个图是二分图. 为什么? 横纵坐标为奇数的只会和横纵坐标为偶数的相连. ...

  8. HDU 1569 方格取数(2)

    方格取数(2) Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 15 ...

  9. 【最小割/二分图最大独立集】【网络流24题】【P2774】 方格取数问题

    Description 给定一个 \(n~\times~m\) 的矩阵,每个位置有一个正整数,选择一些互不相邻的数,最大化权值和 Limitation \(1~\leq~n,~m~\leq~100\) ...

随机推荐

  1. 【译】NCCloud: Applying Network Coding for the Storage Repair in a Cloud-of-Clouds

    NCCloud:多云存储设备下存储修复的网络编码 Yuchong Hu, Henry C. H. Chen, Patrick P. C. Lee, Yang Tang  摘要:近年来的研究提出通过条带 ...

  2. cf575A Fibonotci

    Fibonotci sequence is an integer recursive sequence defined by the recurrence relation Fn = sn - 1·F ...

  3. 美丽的大树(codevs 2124)

    题目描述 Description 平江路是苏州最美丽的道路,路中间的绿化带上种了两行漂亮的大树,每行50棵,一共100棵大树,这些大树被编上了号,编号方式如下: 1 3 5 7 ………… 45 47 ...

  4. 解决PHP无法接收post超过1000个字段的问题

    今天在做与后台交互的的过程中,发现php对于接收的POST有一个限制,超出1000个字段之后便无法接收,项目要求在不改变PHP配置的情况下通过前端方式解决,通过分析并且网上差一些大牛的资料终于找到了解 ...

  5. 如何用Eclipse将普通的JavaWeb项目转为Maven项目

    最新自己的第一个项目差不多稳定运行之后 想着将项目转为Maven项目.于是参考网上成功的将自己的普通的项目转为了maven项目,现在记录一下: 0.普通的java项目的结构如下: 1.接下来开始进行正 ...

  6. C++练习,计算间隔天数

    time_t time(time_t *time) 从1970年1月1日到到现在的秒数,如果系统时间不存在,返回1char *ctime(const time_t *time) 返回以:day mon ...

  7. Python爬虫--beautifulsoup 4 用法

    Beautiful Soup将复杂HTML文档转换成一个复杂的树形结构, 每个节点都是Python对象,所有对象可以归纳为4种: Tag , NavigableString , BeautifulSo ...

  8. Access restriction: The method 'CharacterEncoder.encode(byte[])' is not API...

    问题描述:Access restriction: The method 'CharacterEncoder.encode(byte[])' is not API... 解决方法:这种错误是eclips ...

  9. PPT中的图像失真

    现象:Office PowerPoint 保存出来的PPT文件在WPS下播放的时候会出现图像失真的显现. 解决方法:Office PowerPoint打开PPT将里面的图像另存为BMP格式的图像文件, ...

  10. BUPT复试专题—最小距离查询(2013)

    题目描述 给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始).你需要完成下面两个操作:INSERT c  其中c是一个待输入的字符.你需要在字符串的末尾添加这个字符.保证 ...