HDU1569 方格取数(2) —— 二分图点带权最大独立集、最小割最大流
题目链接: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
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
75 15 21
75 15 28
34 70 5
题解:
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) —— 二分图点带权最大独立集、最小割最大流的更多相关文章
- HDU1565 方格取数(1) —— 状压DP or 插头DP(轮廓线更新) or 二分图点带权最大独立集(最小割最大流)
题目链接:https://vjudge.net/problem/HDU-1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...
- hdu1569 方格取数 求最大点权独立集
题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和.思路:建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),问题转化为求总权和-最小点权覆盖集(点 ...
- BZOJ 1475 方格取数(二分图最大点权独立集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1475 [题目大意] 给出一个n*n的方格,从中取一些不相邻的数字,使得和最大 [题解] ...
- 洛谷 - P2774 - 方格取数问题 - 二分图最大独立点集 - 最小割
https://www.luogu.org/problemnew/show/P2774 把两个相邻的节点连边,这些边就是要方便最小割割断其他边存在的,容量无穷. 这种类似的问题的话,把二分图的一部分( ...
- luogu2774 方格取数问题 二分图最小权点覆盖集
题目大意:在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意 2 个数所在方格没有公共边,输出这些数之和的最大值. 思路:这种各个点之间互相排斥求最大值的题,往往需要利 ...
- Luogu_2774 方格取数问题
Luogu_2774 方格取数问题 二分图最小割 第一次做这种题,对于某些强烈暗示性的条件并没有理解到. 也就是每一立刻理解到是这个图是二分图. 为什么? 横纵坐标为奇数的只会和横纵坐标为偶数的相连. ...
- HDU 1569 方格取数(2)
方格取数(2) Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 15 ...
- 【最小割/二分图最大独立集】【网络流24题】【P2774】 方格取数问题
Description 给定一个 \(n~\times~m\) 的矩阵,每个位置有一个正整数,选择一些互不相邻的数,最大化权值和 Limitation \(1~\leq~n,~m~\leq~100\) ...
随机推荐
- Ionic 如何把左上角的按钮去掉?
代码实现: <ion-header > <ion-toolbar> <ion-buttons start> <a href="#"> ...
- 把项目变成intellij idea和eclipse项目
就通过maven把它build成一个IDE项目,执行以下命令,打开CMD: $ cd 项目名 $ mvn eclipse:eclipse or mvn idea:idea
- kubernetes---CentOS7安装kubernetes1.11.2图文完整版
转载请注明出处:kubernetes-CentOS7安装kubernetes1.11.2图文完整版 架构规划 k8s至少需要一个master和一个node才能组成一个可用集群. 本章我们搭建一个mas ...
- CPU 和内存虚拟化原理
前面我们成功地把 KVM 跑起来了,有了些感性认识,这个对于初学者非常重要.不过还不够,我们多少得了解一些 KVM 的实现机制,这对以后的工作会有帮助. CPU 虚拟化 KVM 的虚拟化是需要 CPU ...
- noip2013华容道
题目描述 [问题描述] 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面, 华容道是否根本就无法完成,如果能完成, 最少需要多少时间. 小 ...
- HBase总结
1.HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”.就像Bigtable利用了Google ...
- js long类型的日期转成Date,字符串StringBuilder拼接
longToDate.js //扩展Date的format方法 Date.prototype.format = function (format) { var o = { "M+" ...
- C# 把控件内容导出图片
Bitmap newbitmap = new Bitmap(panelW.Width, panelW.Height); panelW.DrawToBitmap(newbitmap ...
- 反混淆:恢复被OLLVM保护的程序
译者序: OLLVM作为代码混淆的优秀开源项目,在国内主流app加固应用中也经常能看到它的身影,但是公开的分析研究资料寥寥.本文是Quarkslab团队技术博客中一篇关于反混淆的文章,对OLLVM项目 ...
- c++中c_str()函数
https://zhidao.baidu.com/question/104592558.html