HDU 1569 方格取数(2)
来源:互联网 发布:怎样学java编程基础 编辑:程序博客网 时间:2024/04/29 13:21
方格取数(2)
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2878 Accepted Submission(s): 871
Problem Description
给你一个m*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大。
Input
包括多个测试实例,每个测试实例包括2整数m,n和m*n个非负数(m<=50,n<=50)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3 375 15 21 75 15 28 34 70 5
Sample Output
188
Author
ailyanlu
Source
Happy 2007
Recommend
8600
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <string>#include <queue>#include <stack>#include <map>#include <set>#include <list>#define INT_INF 0x3fffffff#define LL_INF 0x3fffffffffffffff#define EPS 1e-12#define MOD 1000000007#define PI 3.141592653579798#define N 3000#define E 100000using namespace std;typedef long long LL;typedef unsigned long long ULL;typedef double DB;const int zl[4][2]={{1,0},{-1,0},{0,1},{0,-1}};struct Edge{ int en,cap,flow,next;} edge[E];int head[N] , tot , now[N];int source,sink,tot_num;int pre[N] , dis[N] , gap[N];void add_edge(int st,int en,int cap){ edge[tot].en=en; edge[tot].cap=cap; edge[tot].flow=0; edge[tot].next=head[st]; head[st]=tot++; edge[tot].en=st; edge[tot].cap=0; edge[tot].flow=0; edge[tot].next=head[en]; head[en]=tot++;}void augment(int flow){ for(int i=source;i!=sink;i=edge[now[i]].en) { edge[now[i]].flow+=flow; edge[now[i]^1].flow-=flow; }}int sap(){ memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); memset(pre,-1,sizeof(pre)); for(int i=0;i<tot_num;i++) now[i]=head[i]; gap[0]=tot_num; int point=source,flow=0,min_flow=INT_INF; while(dis[source]<tot_num) { bool fg=false; for(int i=now[point];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow>0 && dis[point]==dis[edge[i].en]+1) { min_flow=min(min_flow,edge[i].cap-edge[i].flow); now[point]=i; pre[edge[i].en]=point; point=edge[i].en; if(point==sink) { flow+=min_flow; augment(min_flow); point=source; min_flow=INT_INF; } fg=true; break; } if(fg) continue; if(--gap[dis[point]]==0) break; int Min=tot_num; for(int i=head[point];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow>0 && Min>dis[edge[i].en]) { Min=dis[edge[i].en]; now[point]=i; } gap[dis[point]=Min+1]++; if(point!=source) point=pre[point]; } return flow;}int build(int n,int m){ memset(head,-1,sizeof(head)); tot=0; int ans=0; source=N-2; sink=N-1; tot_num=N; for(int i=0; i<n; i++) for(int j=0,pos,val; j<m; j++) { scanf("%d",&val); ans+=val; pos=i*m+j; if((i+j)%2==0) add_edge(pos,sink,val); else { add_edge(source,pos,val); for(int k=0; k<4; k++) { if(i+zl[k][0]>=0 && i+zl[k][0]<n && j+zl[k][1]>=0 && j+zl[k][1]<m) add_edge(pos,(i+zl[k][0])*m+j+zl[k][1],INT_INF); } } } return ans;}int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF) { int ans=build(n,m); ans-=sap(); printf("%d\n",ans); } return 0;}
- hdu 1569 方格取数(2)
- hdu 1569 方格取数(2)
- HDU 1569 方格取数(2)
- hdu 1569 方格取数(2)
- HDU 1569 方格取数(2)
- hdu 1569 方格取数(2)
- HDU 1569 方格取数(2)
- 方格取数(2) HDU
- hdu 1565 方格取数(1) and hdu 1569 方格取数(2)
- hdu 1565 方格取数(1)/hdu 1569 方格取数(2)(最小割,黑白染色)
- hdu 1569 方格取数(2)//最小割
- hdu 1569 方格取数(2) (最大流最小割)
- hdu 1569 方格取数(2) 最大权独立集
- hdu(1569)方格取数(2)(dinic算法)
- HDU 1569——方格取数(2) 【不用vector】
- 【网络流】hdu 1569 方格取数(2)
- 【网络流】 hdu 1569 方格取数(2)
- 【网络流】 HDU 1569 方格取数(2)
- lucene.Net--学习笔记(3)---C#'网络爬虫' 源码详解
- BOOST.SERIALIZE序列化对象
- HDU 2686 Matrix
- JavaScript学习笔记(五) 让函数成为构造函数
- Ubuntu安装Apache
- HDU 1569 方格取数(2)
- Eclipse汉化教程
- html初步之三
- QtClose消息
- 详解String 和 StringBuffer 区别
- typedef用法小结(比较好)
- 活出个人样来 (文/金心浪子)
- springgraph
- HDU 1565 方格取数(1)