codevs 1907 方格取数 3
Description
在一个有m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。
Input
第1 行有2 个正整数m和n,分别表示棋盘的行数和列数。接下来的m行,每行有n个正整数,表示棋盘方格中的数。
Output
对于给定的方格棋盘,按照取数要求编程找出总和最大的数,将取数的最大总和输出。
Sample Input
3 3
1 2 3
3 2 3
2 3 1
Sample Output
11
HINT
n,m<=30
嗯......这道题大概算是自己想出来的第一道网络流的题吧?
虽然想了很久,WA了很多发,但终于A掉了......
网络流的题真是难想(但这一题还是比较简单的),如果不是我已经知道这道题要用网络流做,还不知道要想到什么时候去了......
好了,不扯多了,进正题:
首先,我们发现直接建模的话非常不好搞,体重的条件不好表示......
于是,我们就想,是否可以把我们选完数之后剩下的数给表示出来呢?我们发现这个不难做到。只需将棋盘黑白二染色,把黑点、白点各看成一块,相邻的格子间有边相连,不难发现将黑白两块分开的割的方案就是不选的点的合法方案(脑补一下应该可以搞出来)。所以最小割即是合法方案中选出的点和最大的方案。于是我们可以从源点向所有黑(白)点连一条容量为这个格子里的数的边,从黑(白)点向相邻的点连一条容量为INF的边,再从白(黑)点向汇点连一条容量为当前格子里的数的边,跑一边最大流即可得出不选的点的最小和,用所有数字之和减去它就是答案。
update:其实这就是最大独立集等于总点数减去最大匹配数
下面贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxm 100010
#define INF (1<<25)
#define r(j) (j^1) using namespace std;
typedef long long llg; int head[*],next[maxm],to[maxm],c[maxm],tt=;
int a[][],zx[]={,,,-},zy[]={,-,,};
int d[maxm],l,r,dep[maxm],ans,tut,s,t,n,m; int getint(){
int w=;bool q=;
char c=getchar();
while((c>''||c<'')&&c!='-') c=getchar();
if(c=='-') q=,c=getchar();
while(c>=''&&c<='') w=w*+c-'',c=getchar();
return q?-w:w;
} void link(int x,int y,int z){
to[++tt]=y;next[tt]=head[x];head[x]=tt;
to[++tt]=x;next[tt]=head[y];head[y]=tt;
c[tt^]=z;
} bool bfs(){
for(int i=;i<=t;i++) dep[i]=;
l=r=;d[r++]=s;dep[s]=;int u;
while(l!=r){
u=d[l++];
for(int i=head[u];i;i=next[i])
if(!dep[to[i]] && c[i]>){
dep[to[i]]=dep[u]+;
d[r++]=to[i];
}
}
return dep[t]>;
} int dfs(int u,int low){
int res=,v;
if(u==t) return low;
if(!low) return ;
for(int i=head[u];i;i=next[i])
if(c[i]> && dep[to[i]]==dep[u]+){
v=dfs(to[i],min(low-res,c[i]));
c[i]-=v;c[r(i)]+=v;res+=v;
}
return res;
} int main(){
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
n=getint();m=getint();s=n*m+;t=s+;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
a[i][j]=getint();
for(int i=,now();i<=n;i++)
for(int j=;j<=m;j++){
now++;
if(!((i+j)&)){
link(s,now,a[i][j]);
for(int k=,x,y,n1;k<;k++){
x=i+zx[k];y=j+zy[k];
if(x> && x<=n && y> && y<=m){
n1=(x-)*m+y;
link(now,n1,INF);
}
}
}
else link(now,t,a[i][j]);
tut+=a[i][j];
}
while(bfs())
while(int tot=dfs(s,INF)) ans+=tot;
printf("%d\n",tut-ans);
return ;
}
codevs 1907 方格取数 3的更多相关文章
- Codevs 1043 方格取数
1043 方格取数 2000年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Descri ...
- Codevs 1227 方格取数 2(费用流)
1227 方格取数 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 大师 Master 查看运行结果 题目描述 Description 给出一个n*n的矩阵,每一格有一个非负整数 ...
- 【wikioi】1907 方格取数3(最大流+最大权闭合子图)
http://www.wikioi.com/problem/1907/ 这题我一开始想到的是状压,看到n<=30果断放弃. 然后也想到了黑白染色,然后脑残了,没想到怎么连边. 很简单的一题 黑白 ...
- codevs 1227 方格取数 2
Description 给出一个n*n的矩阵,每一格有一个非负整数Aij,(Aij <= 1000)现在从(1,1)出发,可以往右或者往下走,最后到达(n,n),每达到一格,把该格子的数取出来, ...
- codevs——T1043 方格取数
http://codevs.cn/problem/1043/ 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 De ...
- codevs 1043 方格取数 2000年NOIP全国联赛提高组
时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 设有N*N的方格图(N<=10,我们将其中的某些方格中填入正整数,而 ...
- codevs 方格取数
1043 方格取数 2000年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Descri ...
- tyvj 1884 [NOIP2000T4]方格取数 || codevs 1043 dp
P1884 [NOIP2000T4]方格取数 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 [noip2000T4]方格取数 描述 设有N*N的方格图(N& ...
- 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏
P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...
随机推荐
- c中的指针
一. 指针前奏 1. 指针的重要性 指针是C语言中非常重要的数据类型,如果你说C语言中除了指针,其他你都学得很好,那你干脆说没学过C语言. 2. 小需求 l void change(int n)函数 ...
- 列式存储(二)JFinal如何处理从前台传回来的二维数组
上一篇说到了列式存储,这一篇说它的存储问题,将每个模块的所有属性字段单独存到一张表中,新增页面时,所有的字段都去数据库请求,这样多个模块的新增功能可以共用一个jsp.由于每个模块的字段个数不一样,有的 ...
- GitHub 上有哪些完整的 iOS-App 源码值得参考?
1. Coding iOS 客户端 Coding官方客户端. 笔者强烈推荐的值得学习的完整APP.GitHub - Coding/Coding-iOS: Coding iOS 客户端源代码 2. OS ...
- MicroStation VBA 可视化界面
第十章 可视界面 Private Sub UserForm_Initialize() Dim ViewCen As Point3d Dim MyView As View For Each MyView ...
- Java虚拟机内存管理原理基础入门
Jdk:Java程序设计语言.Java虚拟机.Java API类库. Jdk是用于支持Java程序开发的最小环境. Jre:Java API类库中的Java SE API子集.Java虚拟机. Jre ...
- Softmax回归(Softmax Regression)
转载请注明出处:http://www.cnblogs.com/BYRans/ 多分类问题 在一个多分类问题中,因变量y有k个取值,即.例如在邮件分类问题中,我们要把邮件分为垃圾邮件.个人邮件.工作邮件 ...
- JavaScript中产生标识符方式的演变
本文记录下JS中产生标示符方式的演变,从ES5到ES6,ES5及其之前是一种方式,只包含两种声明(var/function),ES6则增加了一些产生标识符的关键字,如 let.const.class. ...
- linux进程间通信-消息队列
一 消息队列的介绍 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构. 我们可以通过发送消息来避免命名管道的 ...
- 大话设计模式C++版——表驱动法改造简单工厂
上回<大话设计模式C++版——简单工厂模式>中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码 ...
- [转]android 获取视频帧
本文转自:http://blog.csdn.net/heart_Moving/article/details/17414067 今天做Android视频文件解码,需求:从一个视频文件获取到一帧一帧的图 ...