codevs1907 方格取数 3
«问题描述:
在一个有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
正解:网络流
解题报告:
同HDU1565,我的题解的传送门:http://www.cnblogs.com/ljh2000-jump/p/5756667.html
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #ifdef WIN32 14 #define OT "%I64d" 15 #else 16 #define OT "%lld" 17 #endif 18 using namespace std; 19 typedef long long LL; 20 const int MAXN = 501; 21 const int MAXM = 500011; 22 const int inf = (1<<30); 23 int m,n,sum,S,T,ecnt,ans; 24 int a[MAXN][MAXN],deep[MAXN*MAXN]; 25 int first[MAXN*MAXN]; 26 queue<int>Q; 27 struct edge{ 28 int next,to,f; 29 }e[MAXM]; 30 31 inline int getint() 32 { 33 int w=0,q=0; 34 char c=getchar(); 35 while((c<'0' || c>'9') && c!='-') c=getchar(); 36 if (c=='-') q=1, c=getchar(); 37 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); 38 return q ? -w : w; 39 } 40 41 inline void link(int x,int y,int z){ 42 e[++ecnt].next=first[x]; first[x]=ecnt; e[ecnt].to=y; e[ecnt].f=z; 43 e[++ecnt].next=first[y]; first[y]=ecnt; e[ecnt].to=x; e[ecnt].f=0; 44 } 45 46 inline bool bfs(){ 47 while(!Q.empty()) Q.pop(); 48 for(int i=1;i<=T;i++) deep[i]=0; 49 Q.push(S); deep[S]=1; 50 while(!Q.empty()) { 51 int u=Q.front(); Q.pop(); 52 for(int i=first[u];i;i=e[i].next) { 53 int v=e[i].to; 54 if(e[i].f && !deep[v]) deep[v]=deep[u]+1,Q.push(v); 55 } 56 } 57 if(deep[T]!=0) return true; 58 return false; 59 } 60 61 inline int Dinic(int x,int remain){ 62 if(remain==0 || x==T) return remain; 63 int f,flow=0; 64 for(int i=first[x];i;i=e[i].next) { 65 int v=e[i].to; 66 if(e[i].f && deep[v]==deep[x]+1){ 67 f=Dinic(v,min(remain,e[i].f)); 68 if(f){ 69 flow+=f; e[i].f-=f; e[i^1].f+=f; 70 remain-=f; if(remain==0) return flow; 71 } else deep[v]=-1; 72 } 73 } 74 return flow; 75 } 76 77 inline void work(){ 78 m=getint(); n=getint(); 79 for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) a[i][j]=getint(),sum+=a[i][j]; 80 S=m*n+1;T=S+1; ecnt=1; 81 for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) if((i+j)%2==0) link(S,(i-1)*n+j,a[i][j]); else link((i-1)*n+j,T,a[i][j]);//黑白染色 82 for(int i=1;i<=m;i++) 83 for(int j=1;j<=n;j++){ 84 if((i+j)%2) continue; 85 if(i!=1) link((i-1)*n+j,(i-2)*n+j,inf); 86 if(j!=1) link((i-1)*n+j,(i-1)*n+j-1,inf); 87 if(j!=n) link((i-1)*n+j,(i-1)*n+j+1,inf); 88 if(i!=m) link((i-1)*n+j,i*n+j,inf); 89 } 90 while(bfs()) ans+=Dinic(S,inf); 91 printf("%d",sum-ans); 92 } 93 94 int main() 95 { 96 work(); 97 return 0; 98 }
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!