方格取数(2)

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 68 Accepted Submission(s): 33
 
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
Happy 2007
 

代码:

//类似于二分图中求最大独立集,但这里带权值。看成二分图,把点数换成奇偶数,(x+y为奇/偶),
//因为奇数和偶数相邻不能同时取,我们把相互冲突的做边(权值为无穷大),左边加一个源点
//连接所有奇数,右边加一个汇点连接所有偶数(权值为点权值,建边时边的方向要一致),就有了
//最大流模型,最大流求出来的就是最小点权覆盖。二分图中 最大独立集=总点数-最小点覆盖(最
//大匹配);类似 最大点权独立集=总点权值-最小点权覆盖
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int maxn=,inf=0x7fffffff;
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[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
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<(int)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<(int)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;
}
}dc;
int main()
{
int m,n;
while(scanf("%d%d",&m,&n)==){
int sum=,tmp[][];
for(int i=;i<=m;i++)
for(int j=;j<=n;j++){
scanf("%d",&tmp[i][j]);
sum+=tmp[i][j];
}
dc.init(n*m+);
int s=,t=n*m+;
for(int i=;i<=m;i++)
for(int j=;j<=n;j++){
int nu=(i-)*n+j;
if((i+j)%){
dc.addedge(s,nu,tmp[i][j]);
if(i>) dc.addedge(nu,nu-n,inf);
if(i<m) dc.addedge(nu,nu+n,inf);
if(j>) dc.addedge(nu,nu-,inf);
if(j<n) dc.addedge(nu,nu+,inf);
}
else dc.addedge(nu,t,tmp[i][j]);
}
int x=dc.maxflow(s,t);
printf("%d\n",sum-x);
}
return ;
}

HDU1569 最大流(最大点权独立集)的更多相关文章

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

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

  2. hdu1565+hdu1569(最大点权独立集)

    传送门:hdu1565 方格取数(1) 传送门:hdu1569 方格取数(2) 定理:1. 最小点权覆盖集=最小割=最大流2. 最大点权独立集=总权-最小点权覆盖集 步骤: 1. 先染色,取一个点染白 ...

  3. LibreOJ #6007. 「网络流 24 题」方格取数 最小割 最大点权独立集 最大流

    #6007. 「网络流 24 题」方格取数 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

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

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

  5. HDU 1565 最大点权独立集

    首先要明白图论的几个定义: 点覆盖.最小点覆盖: 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是“点” 覆盖了所有“边”.. 最小点覆盖(minimum vertex covering ...

  6. 【最大点权独立集】【HDU1565】【方格取数】

    题目大意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 初看: 没想法 ...

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

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

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

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...

  9. 最小点权覆盖集&最大点权独立集

    最小点权覆盖集 二分图最小点权覆盖集解决的是这样一个问题: 在二分图中,对于每条边,两个端点至少选一个,求所选取的点最小权值和. 方法: 1.先对图二分染色,对于每条边两端点的颜色不同 2.然后建立源 ...

随机推荐

  1. 将Render博客搬至GIT(偷懒)

    SmallEngine 一个特别小的研究引擎[用于各种实验] 框架上设计上采用Unreal.Unity的设计思路[偷懒了] https://github.com/daozhangXDZ/DZSmall ...

  2. tomcat下载、安装

    下载 官网地址:https://tomcat.apache.org/download-80.cgi 安装 直接安装即可.安装完毕后Tomcat的目录结构如下: bin:脚本目录 ​ 启动脚本:star ...

  3. 150命令之线上查询及帮助命令 man hellp

    150命令之线上查询及帮助命令 man 查询命令的帮助 man + 命令 NAME        ls - list directory contents 命令+命令简单说明   SYNOPSIS   ...

  4. redis 编译安装错误问题

    编译redis安装的时候报错如下: make[1]: [persist-settings] Error 2 (ignored) CC adlist.o/bin/sh: cc: command not ...

  5. Cannot retrieve repository metadata (repomd.xml) for repository: base. Please verify its path and try again YUM报错

        1.挂盘 ----- 2.# mount /dev/sr0 /media/ mount: block device /dev/sr0 is write-protected, mounting ...

  6. 什么是Frozen Binary

    对于Python来说,你可以将Python的字节码,PVM(也就是解析器),以及需要的相关类库,打包成一个package,这个package实际上是一个二进制可执行文件,这样,用户获取到这个packa ...

  7. python学习摘要(2)--基本数据类型

    python申请存储空间是动态的.变量如同指针一样指向存储空间.多个变量会指向同一个存储空间(节省空间).当变量改变时,原来的地址单元并不会马上释放.(引用计数自行回收) c/c++根基性语言,想要什 ...

  8. JSON解析与序列化

    JSON之所以流行,拥有与JavaScript类似的语法并不是全部原因.更重要的一个原因是,可以把JSON数据结构解析为有用的 JavaScript对象.与XML数据结构要解析成DOM文档而且从中提取 ...

  9. 软工网络15团队作业——Alpha阶段敏捷冲刺 DAY1

    Alpha阶段敏捷冲刺 DAY1 1.各个成员在 Alpha 阶段认领的任务 姓名 在Alpha阶段所认领的任务 陈龙 题目生成类的编写,随机生成合理题目的算法编写 郑佳明 答案计算类的编写,对随机生 ...

  10. 修改QQ各版本的默认保存位置(聊天记录)

    这几天没少折腾windows,都有点烦了,我是那种有强迫症的,只要知道的自己没有做到的会感觉到浑身不爽的因为系统重装了好几次,QQ也没少安装几次,我使用的是TM的QQ(没有 那么多烦人的广告,娱乐组件 ...