hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)
/**
转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2)
链接:https://vjudge.net/problem/HDU-1569
题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和。
思路:
建图过程:对于二维矩阵,如果(i+j)%2==0,那么放在X集,s->(i-1)*m+j, cap = 元素值。
否则放在Y集, (i-1)*m+j->t, cap = 元素值。 如果u与v相邻,且u为X集的点,v为Y集的点,u->v,cap = INF. 建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),
问题转化为求总权和-最小点权覆盖集(点集I覆盖所有边,点权之和最小),
(对应于原题,就是求拿掉最小点集,这些点覆盖所有边,拿掉后,每个点必然两两不相邻,
否则:假设u,v相邻,则u->v这条边未被覆盖,矛盾),
在建立超级源汇点s,t,s连向所有X中的点(设二分图G(X,Y)),Y联向t,,权值为点权,
原来X->Y的所有边权值改为inf,问题转化为:求s->t最小割(一组权值和最小的割边集,去掉后s->t不连通),
而每去掉一条割边,相当于去掉原图一个点,这个点必然牵着下面X->Y的边,故最小割即为最小点权覆盖集! (部分证明:摘自某大牛:可以这样理解:X到Y的边权为INF,自然不会成为最小割中的边,那就只有可能
是S到X和Y到T中的边,而:S到X中点x的边e1, 权为点x的点权,点x和Y中的所有临边e2,都需要受
到e1的流量的限制,同样,X到Y中点y的所有边也会受到点y到T的容量限制。这样求得割就能保证覆
盖掉所有的边。
我们可以用反证法证明一下:假设有边<x, y>没有被覆盖掉,则边<S, x>流量为0且边<y, T>流量为0,
而<x, y>流量为INF,自然可以找到一条S到T的增流路径<S, x, y, T>,与以求得流为最大流相矛盾,
则可以说明,在最大流的情况下,所有的边都已经被覆盖掉。) 结论(二分图):最小点权覆盖集=最小割=最大流; 最大点权覆盖集=总权和-最小点权覆盖集 */
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const long long MAS = 1e13;
const int INF = 0x3f3f3f3f;
typedef long long LL;
const int N = *+;///拆点法,注意要乘以个2.
struct Edge{
int from, to, cap, flow;
Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct Dinic{
int n, m, s, t;
vector<Edge> edges;
vector<int> G[N];
bool vis[N];
int d[N];
int cur[N]; void init(int n)
{
this->n = n;
for(int i = ; i <= n; i++) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,));
edges.push_back(Edge(to,from,,));
m = edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
memset(vis, , sizeof vis);
queue<int> Q;
Q.push(s);
d[s] = ;
vis[s] = ;
while(!Q.empty())
{
int x = Q.front();
Q.pop();
for(int i = ; i < G[x].size(); i++)
{
Edge &e = edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to] = ;
d[e.to] = d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if(x==t||a==) return a;
int flow = , f;
for(int &i = cur[x]; i < G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
{
e.flow += f;
edges[G[x][i]^].flow -= f;
flow += f;
a -= f;
if(a==) break;
}
}
return flow;
} int Maxflow(int s,int t)
{
this->s = s, this->t = t;
int flow = ;
while(BFS())
{
memset(cur, , sizeof cur);
flow += DFS(s,INF);
}
return flow;
}
};
int main()
{
int n, m;
while(scanf("%d%d",&n,&m)==)
{
int s = , t = n*m+;
Dinic dinic;
dinic.init(t);
int w;
int sum = ;
for(int i = ; i <= n; i++){
for(int j = ; j <= m; j++){
scanf("%d",&w);
sum += w;
if((i+j)%==){///放左边
dinic.AddEdge(s,(i-)*m+j,w);
if(j+<=m){
dinic.AddEdge((i-)*m+j,(i-)*m+j+,INF);
}
if(j->=){
dinic.AddEdge((i-)*m+j,(i-)*m+j-,INF);
}
if(i+<=n){
dinic.AddEdge((i-)*m+j,i*m+j,INF);
}
if(i->=){
dinic.AddEdge((i-)*m+j,(i-)*m+j,INF);
}
}else///放右边
{
dinic.AddEdge((i-)*m+j,t,w);
}
}
}
printf("%d\n",sum-dinic.Maxflow(s,t));
}
return ;
}
hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)的更多相关文章
- hdu1569 方格取数 求最大点权独立集
题意:一个方格n*m,取出一些点,要求两两不相邻,求最大和.思路:建图,相邻的点有一条边,则建立了一个二分图,求最大点权独立集(所取点两两无公共边,权值和最大),问题转化为求总权和-最小点权覆盖集(点 ...
- HDU 1565 1569 方格取数(最大点权独立集)
HDU 1565 1569 方格取数(最大点权独立集) 题目链接 题意:中文题 思路:最大点权独立集 = 总权值 - 最小割 = 总权值 - 最大流 那么原图周围不能连边,那么就能够分成黑白棋盘.源点 ...
- HDU1569 方格取数(2) —— 二分图点带权最大独立集、最小割最大流
题目链接:https://vjudge.net/problem/HDU-1569 方格取数(2) Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- TZOJ 3665 方格取数(2)(最大点权独立集)
描述 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. 输入 包括多个测试实例 ...
- hdu - 1565 方格取数(1) && 1569 方格取数(2) (最大点权独立集)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 两道题只是数据范围不同,都是求的最大点权独立集. 我们可以把下标之和为奇数的分成一个集合,把下标之和为偶数 ...
- HDU 1569 - 方格取数(2) - [最大点权独立集与最小点权覆盖集]
嗯,这是关于最大点权独立集与最小点权覆盖集的姿势,很简单对吧,然后开始看题. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1569 Time Limi ...
- HDU1565 方格取数(1) —— 状压DP or 插头DP(轮廓线更新) or 二分图点带权最大独立集(最小割最大流)
题目链接:https://vjudge.net/problem/HDU-1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流
#6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
- hdu 4859 最大点权独立集的变形(方格取数的变形)
/*刚开始不会写,最大点权独立集神马都不知道,在潘神的指导下终于做出来,灰常感谢ps: 和方格取数差不多奇偶建图,对于D必割点权为0,对于.必然不割点权为inf.然后和方格取数差不多的建图 .--.| ...
随机推荐
- 【云计算】k8s相关资料
参考资料: How to get started, and achieve tasks, using Kubernetes:http://kubernetes.io/docs/getting-star ...
- 【Web】前台传送JSON格式数据到后台Shell处理
1.js中的json对象和字符串之间的转化:http://www.oschina.net/code/snippet_175925_6288 代码片段: var obj = JSON.parse(des ...
- 【转】编译安装PHP并配置PHP-FPM
1.前言上一篇讲述了如何编译安装MySQL,虽然可以通过yum install 或者rpm来安装,但是yum install和rpm安装有一个特点,就是有些参数是别人根据大众需求定制的,如果需要进行自 ...
- IE测试CSS兼容性测试
我们知道IE6~8是现在浏览器的主流.但是由IE6开始,我们已经知道IE并不是完全执行W3C标准.我们在编程的时候往往遇到只兼容某一种浏览器. 我们以前经常使用IE Test进行IE的兼容性测试.但是 ...
- 微信公众号支付调用chooseWXPay提示“errmsg choosewxpay fail”
微信公众号支付一直提示“errmsg choosewxpay fail”,也没有提示具体错误信息,签名没有问题(签名验证地址:https://pay.weixin.qq.com/wiki/doc/ap ...
- Mach-O文件格式和程序从载入到运行过程
> 之前深入了解过.过去了一年多的时间.如今花些时间好好总结下,毕竟好记性不如烂笔头. 其次另一个目的,对于mach-o文件结构.关于动态载入信息那个数据区中,命令含义没有深刻掰扯清除,希望有同 ...
- poj 2253 (dis最短路径)
Frogger Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 24979 Accepted: 8114 Descript ...
- Browsers 之 弹出窗口阻止问题
主要关注两个地方: 1.Microsoft Edge 浏览器: 浏览器 “ 设置 → 查看高级设置 ”,找到 “ 阻止弹出窗口 ”,关闭. 2.IE浏览器 [1] “ 工具 → 弹出窗口阻止程序 ”, ...
- 从客户端的角度来谈谈移动端IM的消息可靠性和送达机制
1.前言 IM App 是我做过 App 类型里复杂度最高的一类,里面可供深究探讨的技术难点非常之多.这篇文章和大家聊下从移动端客户端的角度所关注的IM消息可靠性和送达机制(因为我个人对移动客户端的经 ...
- linux svn恢复删除的文件夹和文件(转)
我觉得在window下面,查找被删除的svn文件夹和文件是件比较麻烦的事,恢复就更麻烦了.有的时候,命令还是比鼠标要好用的. 下面做一个例子来说明一下,删除和恢复的例子. [root@BlackGho ...