标签:网络 code 正整数 大小 inf space gis amp 二分图
none!
在一个有 m*n 个方格的棋盘中,每个方格中有一个正整数。现要从方格中取数,使任意 2 个数所在方格没有公共边,且取出的数的总和最大。试设计一个满足要求的取数算法。对于给定的方格棋盘,按照取数要求编程找出总和最大的数。
第 1 行有 2 个正整数 m 和 n,分别表示棋盘的行数和列数。接下来的 m 行,每行有 n 个正整数,表示棋盘方格中的数。
输出格式:程序运行结束时,将取数的最大总和输出
3 3
1 2 3
3 2 3
2 3 1
11
m,n<=100
/*Code by 520 -- 8.25*/ #include<bits/stdc++.h> #define il inline #define ll long long #define RE register #define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++) #define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--) #define debug printf("%d %s\n",__LINE__,__FUNCTION__) using namespace std; const int N=100005,inf=233333333,dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}; int n,m,s,t,dis[N],to[N],net[N],w[N],h[N],cnt=1; int mp[105][105],ans; il int id(int x,int y){return (x-1)*m+y;} il void add(int u,int v,int c){ to[++cnt]=v,net[cnt]=h[u],w[cnt]=c,h[u]=cnt; to[++cnt]=u,net[cnt]=h[v],w[cnt]=0,h[v]=cnt; } queue<int>q; il bool bfs(){ memset(dis,-1,sizeof(dis)); q.push(s),dis[s]=0; while(!q.empty()){ RE int u=q.front();q.pop(); for(RE int i=h[u];i;i=net[i]) if(dis[to[i]]==-1&&w[i]) dis[to[i]]=dis[u]+1,q.push(to[i]); } return dis[t]!=-1; } int dfs(int u,int op){ if(u==t)return op; int flow=0,used=0; for(RE int i=h[u];i;i=net[i]){ int v=to[i]; if(dis[to[i]]==dis[u]+1&&w[i]){ used=dfs(to[i],min(op,w[i])); if(!used)continue; flow+=used,op-=used; w[i]-=used,w[i^1]+=used; if(!op)break; } } if(!flow) dis[u]=-1; return flow; } il void init(){ scanf("%d%d",&n,&m),t=n*m+1; For(i,1,n) For(j,1,m) { scanf("%d",&mp[i][j]),ans+=mp[i][j]; (i+j)&1?add(s,id(i,j),mp[i][j]):add(id(i,j),t,mp[i][j]); } For(i,1,n) For(j,1,m) if((i+j)&1) { For(k,0,3){ RE int xx=i+dx[k],yy=j+dy[k]; if(xx>0&&xx<=n&&yy>0&&yy<=m) add(id(i,j),id(xx,yy),inf); } } while(bfs()) ans-=dfs(s,inf); cout<<ans; } int main(){ init(); return 0; }
标签:网络 code 正整数 大小 inf space gis amp 二分图
原文地址:https://www.cnblogs.com/five20/p/9537561.html