1324: Exca王者之剑

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 618  Solved: 310
[Submit][Status][Discuss]

Description

 

Input

第一行给出数字N,M代表行列数.N,M均小于等于100 下面N行M列用于描述数字矩阵

Output

输出最多可以拿到多少块宝石

Sample Input

2 2
1 2
2 1

Sample Output

4

改一下方格尺寸这个题就和方格取数一样了

那么我们来写题解
旨在讲清楚最大点权独立集(最小点权覆盖)的一般解法

题目显然在要求一个最大点权独立集(概念请见传送门)
最大点权独立集与最小点权覆盖是对偶问题,这里先介绍最小点权覆盖的解法。

最小点权覆盖问题是指:
给出一张二分图,二分图的每个节点带有一个点权,要求从中选出若干节点
使得这些节点能够覆盖二分图中所有的边,并使得节点的权值和最小。
该类问题可用网络流最小割算法来解决。
考虑最小割的性质,最小割能够将原图中所有的点划分为两个集合,这能够与最小点权覆盖问题中的点得选中与否对应
如果能够找到一种建模方式
满足在二分图中的每条边连接的两个点中,至少一个被选中,就能使网络流的最小割与二分图的最小点权覆盖相匹配。

于是考虑如下建模方式:
建立源点S,汇点T,保留二分图中的所有节点xi,yi,从S到所有xi连边,权值为xi的权值;
若二分图中xi到yi有边,在网络流图中从xi向yi连边,权值为无穷;从所有yi到T连边,权值为yi的权值。

这样,二分图中的每条边连接的两个点中,要么与S形成割边,要么与T形成割边(因为这两个点之间的边权为inf)
这就保证了两个点中,至少一个被选中,因此最小割就对应了一个最小点权的选点方案。
故网络流图中的最小割就是原问题的最小点权。

而最大点权独立集问题中,需要满足在二分图中的每条边连接的两个点中,选择至多一个,最终是选择的点的点权和最大
换句话说,就是在二分图中的每条边连接的两个点中,至少不选择一个,使得不选择的点的点权和最小。
说到这里,大家应该能看出最大点权独立集合最小点权覆盖问题的联系了:
最大点权独立集=权值和-最小点权覆盖

在了解了解法之后就当然会做啦
我们可以将方格拆成一个二分图;
对于点(i,j):
如果(i+j)为奇数,我们就将其向源点连边;
如果(i+j)为偶数,我们就将其向汇点连边;
我们可以把不能在同一个集合里的点之间连边(也就是上述的两类点),边权设置为无穷大;
然后求出最小割。

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<set>
#include<map>
using namespace std;
inline int read()
{int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return f*x;
}
const int N=10010;const int inf=0X7f7f7f7f;
int n,m,mp[110][110],ecnt=1,last[N],d[N],q[N],ans,S,T=N-2;
struct EDGE{int to,nt,val;}e[N<<5];
inline void readd(int u,int v,int val)
{e[++ecnt]=(EDGE){v,last[u],val};last[u]=ecnt;}
inline void add(int u,int v,int val)
{readd(u,v,val);readd(v,u,0);}
bool bfs()
{memset(d,0,sizeof(d));d[S]=1;int head=0,tail=1;q[0]=S;while(head<tail){int u=q[head++];for(int i=last[u];i;i=e[i].nt)if(e[i].val&&!d[e[i].to]){d[e[i].to]=d[u]+1;q[tail++]=e[i].to;}}return d[T];
}
int dfs(int u,int lim)
{if(u==T||!lim)return lim;int flow=0;for(int i=last[u];i;i=e[i].nt)if(d[e[i].to]==d[u]+1){int tmp=dfs(e[i].to,min(e[i].val,lim));flow+=tmp;lim-=tmp;e[i].val-=tmp;e[i^1].val+=tmp;if(!lim)break;}if(!flow)d[u]=-1;return flow;
}
void dinic()
{while(bfs()){ans+=dfs(S,inf);}}
int main()
{n=read();m=read();int sum=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){mp[i][j]=read();sum+=mp[i][j];if((i+j)%2){add(S,(i-1)*m+j,mp[i][j]);if(j>1)add((i-1)*m+j,(i-1)*m+j-1,inf);if(i>1)add((i-1)*m+j,(i-2)*m+j,inf);}else{add((i-1)*m+j,T,mp[i][j]);if(j>1)add((i-1)*m+j-1,(i-1)*m+j,inf);if(i>1)add((i-2)*m+j,(i-1)*m+j,inf);}}dinic();printf("%d\n",sum-ans);return 0;
}

BZOJ 1324: Exca王者之剑/BZOJ 1475: 方格取数 最大权独立集 最小割相关推荐

  1. 【bzoj1324】Exca王者之剑(8-9 方格取数问题)

    *题目描述: 在一个有m*n (m,n<=100)个方格的棋盘中,每个方格中有一个正整数.现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大.试设计一个满足要求的取数算法, ...

  2. P2774 方格取数问题 网络最大流 割

    P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...

  3. [BZOJ]1324: Exca王者之剑

    题目大意:在一个N*M的网格之中,每个格子上都有一定价值的宝石,Amber可以任意选则一个起始点.并且Amber可以瞬间取走当前所在格子中的宝石,Amber每秒可以走一步,在偶数秒时他周围4格中的宝石 ...

  4. 最小割 ---- 二分图最大独立集(集合冲突模型) ---- 骑士共存 方格取数(网络流24题)

    二分图独立集 定理: 二分图最大独立集=n - 二分图最大匹配 其实二分图独立集是特殊的一种最大权闭合子图.我们根据上文"收益"的思想,把选某个点的收益看为1,左部节点为正权点,右 ...

  5. 【网络流24题】I、 方格取数问题(二分图的最大独立集/最小割)

    I. 方格取数问题(二分图的最大独立集/最小割) [问题分析] 二分图点权最大独立集,转化为最小割模型,从而用最大流解决. [建模方法] 首先把棋盘黑白染色,使相邻格子颜色不同,所有黑色格子看做二分图 ...

  6. hdu2167 方格取数 状态压缩dp

    题意:      方格取数,八个方向的限制. 思路:      八个方向的不能用最大流了,四个的可以,八个的不能抽象成二分图,所以目测只能用dp来跑,dp[i][j]表示的是第i行j状态的最优,具体看 ...

  7. hdu 1565 方格取数(1)(状态压缩dp)

    方格取数(1)                                                                 Time Limit: 10000/5000 MS (J ...

  8. [codevs 1907] 方格取数3

    [codevs 1907] 方格取数3 题解: 二分图染色.最大点权独立集. 因为要用到最大独立集的一些思路,故先写了一篇最大独立集的题解:http://blog.csdn.net/qq_211102 ...

  9. [codevs 1227] 方格取数2

    [codevs 1227] 方格取数 2 题解: 注:这是CODEVS的方格取数2,走k次的版本. 因为每个格子可以走无数次,但走过一次之后数字就变成了0,也就是只有一次可以加上格子里的数字.所以要拆 ...

最新文章

  1. tomcat 7.0 linux下载,Tomcat 7.0.67 发布下载
  2. linux学习:进程间通信—管道
  3. Java Collection
  4. matlab怎么实现循环,matlab怎么实现直到型循环
  5. C语言再学习 -- 关键字struct(转)
  6. U-GAT-IT中的一些细节以及变量含义
  7. 用Apache HttpClient实现URL重定向
  8. Java编程思想 (1~10)
  9. Linux使用rostopic echo将rosbag文件转换成csv或txt文件以及sh脚本批量化操作
  10. Helm 3 完整教程(十四):Helm 函数讲解(8)数学计算函数
  11. Python爬虫之模拟CSDN网站登录
  12. 红外图像和可见光图像异源图像配准问题研究
  13. App Store 或涉嫌垄断和违法,开发者拟集体诉讼
  14. 使用Python 批量转移*.tif和*.mov文件
  15. 锐龙R3 3100和R3 3300X对比 哪个好
  16. Excel自动生成条码工具
  17. matlab生成n阶O型方阵,matlab教程 06
  18. 让复选框实现单选功能
  19. zabbix微信告警(虚拟机脚本测试成功,zabbix上收不到信息)
  20. AD域部署软件自动下发

热门文章

  1. linx开发环境搭建
  2. 获得理想薪资的11大技巧
  3. html5动画模板_使基本HTML模板更上一层楼的动画
  4. ChatGPT将颠覆我们生活?
  5. Python 数据挖掘与机器学习进阶实训-2-韦玮-专题视频课程
  6. java.net.UnknownHostException: Unable to resolve host api1.51zhenghao.cn: No address associated wi
  7. java控制台输出颜色设置
  8. 什么是通用离散传感器
  9. Nginx常见场景代理转发配置
  10. 微信浏览器 html5 语音,html5录音支持pc和Android、ios部分浏览器,微信也是支持的,JavaScript getUserMedia...