【codevs 1902】方格取数3(最小割)
来源:互联网 发布:程序员年入百万 编辑:程序博客网 时间:2024/05/17 08:36
1907 方格取数 3
时间限制: 2 s 空间限制: 256000 KB 题目等级 : 大师 Master
题目描述 Description在一个有m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。
«编程任务:对于给定的方格棋盘,按照取数要求编程找出总和最大的数。
输入描述 Input Description
第1 行有2 个正整数m和n,分别表示棋盘的行数和列数。接下来的m行,每行有n个正整数,表示棋盘方格中的数。
输出描述 Output Description
将取数的最大总和输出
样例输入 Sample Input
3 3
1 2 3
3 2 3
2 3 1
样例输出 Sample Output
11
数据范围及提示 Data Size & Hint
n,m<=30
【题解】【网络流最小割】
【黑白染色,将相邻两个格染上不同的颜色,将源点与白点连边,黑点与汇点连边,流量为当前格中的值。再将相邻的点连边,流量为极大值。然后跑最小割(注:最小割=最大流),故直接跑最大流,最后用所有数的和减去最大流】
#include<queue>#include<cstdio>#include<cstring>#include<algorithm>#define lng 10000000using namespace std;int a[10010],next[10010],p[10010],remain[10010],tot;int dis[10010],cur[10010];int n,m,ans,sum,n1,cnt,as;inline void add(int x,int y,int z){tot++; a[tot]=y; next[tot]=p[x]; p[x]=tot; remain[tot]=z;tot++; a[tot]=x; next[tot]=p[y]; p[y]=tot; remain[tot]=0;return;}inline bool bfs(){memset(dis,-1,sizeof(dis));queue<int>que;for (int i=0;i<=n1;++i) cur[i]=p[i]; que.push(0); dis[0]=0;while (!que.empty()) { int u,v; u=que.front(); que.pop(); v=p[u]; while (v!=-1) { if (remain[v]&&dis[a[v]]<0) { dis[a[v]]=dis[u]+1; que.push(a[v]); } v=next[v]; } }if (dis[n1]<0) return false; else return true;}inline int dfs(int now,int flow){if (now==n1||!flow) return flow;int u=cur[now],s;while (u!=-1) { cur[now]=u;if (dis[a[u]]>0&&dis[a[u]]==dis[now]+1&&(s=dfs(a[u],min(flow,remain[u])))) { remain[u]-=s; remain[u^1]+=s; return s; } u=next[u]; }return 0;}int main(){int i,j;memset(p,-1,sizeof(p));memset(next,-1,sizeof(next));scanf("%d%d",&n,&m);n1=n*m+1;as=ans=sum=cnt=0; tot=-1;for (i=1;i<=n;++i) for (j=1;j<=m;++j) { int x; cnt++; scanf("%d",&x); ans+=x; if (i%2==j%2) { add(0,cnt,x);if (i==1) add(cnt,cnt+m,lng); if (i==n) add(cnt,cnt-m,lng); if (i>1&&i<n) {add(cnt,cnt+m,lng); add(cnt,cnt-m,lng);} if (j==1) add(cnt,cnt+1,lng); if (j==m) add(cnt,cnt-1,lng); if (j>1&&j<m) {add(cnt,cnt+1,lng); add(cnt,cnt-1,lng);} } else add(cnt,n1,x); }while (bfs()) while (as=dfs(0,0x7fffffff)) sum+=as; ans-=sum; printf("%d\n",ans); return 0;}
0 0
- 【codevs 1902】方格取数3(最小割)
- Codevs 1907 方格取数 3 最小割
- [codevs1907]方格取数3 最小割
- 方格取数(2) (最小割)
- [CODEVS1907]方格取数3(最小割)
- HDU 1569 方格取数(2)(最小割)
- HDU 1565 方格取数(1)(最小割-Dinic)
- hdu 1565 方格取数(1)(最小割)
- HDU 1565 1569 方格取数 (最小割)
- bzoj 1475: 方格取数 (最小割)
- HDU:1569:方格取数(2)(最小割)
- hdu 3657 Game(最小割,方格取数)
- HDU 1569 方格取数 最小割
- HDU_1569 方格取数(2) 最小割
- hdu1565 hdu1569 方格取数 最小割
- 方格取数 hdu 1565 最小割
- bzoj 1475: 方格取数 最小割
- BZOJ 1475 方格取数【最小割】
- tcp窗口滑动以及拥塞控制
- 等待
- Entity Framework Fluent API and Indexing
- 求一个整数N,二进制中1的个数
- Leetcode 113. Path Sum II 路径和2 解题报告
- 【codevs 1902】方格取数3(最小割)
- Oracle 分区表相关语法
- Lua语法学习笔记(二)
- python笔记 ---蛋疼的 动态类型+强类型语言
- 一些CSS和浏览器之间的怪异显示及对应的解决办法
- 如何在ecs上面配置php环境
- Collection接口和Map接口的主要实现类
- 使用PHP生成短网址的方案
- React从使用到源码学习(一)