自闭了
把方格图黑白染色,然后转化为最小割模型就行了
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int M=11000;
const int N=110;
struct node{
int u,to,w;
};
node edge[M<<1];
int arrange[M],head[M],a[N][N],cur[M];
int n,m,S,T,k,Ans;
void add(int x,int y,int z){
edge[k].u=y; edge[k].to=head[x]; edge[k].w=z; head[x]=k++;
edge[k].u=x; edge[k].to=head[y]; edge[k].w=0; head[y]=k++;
}
bool bfs() {
queue<int>q;
q.push(S);
memset(arrange,0,sizeof(arrange));
arrange[S]=1;
while (!q.empty()) {
int v=q.front(); q.pop(); if (v==T) return 1;
for (int i=head[v];i!=-1;i=edge[i].to) {
int u=edge[i].u;
if (edge[i].w&&!arrange[u]) {
arrange[u]=arrange[v]+1;
q.push(u);
}
}
}
return 0;
}
int dfs(int now,int maxlow,int t) {
if (now==t) return maxlow;
int ret=0;
for (int &i=cur[now];i!=-1;i=edge[i].to) {
int u=edge[i].u;
if (arrange[u]==arrange[now]+1&&edge[i].w) {
int f=dfs(u,min(maxlow-ret,edge[i].w),t); ret+=f;
edge[i].w-=f; edge[i^1].w+=f;
if (ret==maxlow) return ret;
}
}
return ret;
}
int dinic() {
int ans=0;
while (bfs()) {
memcpy(cur,head,sizeof(head));
ans+=dfs(S,INF,T);
}
return ans;
}
int main() {
scanf("%d%d",&n,&m);
memset(head,-1,sizeof(head));
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) scanf("%d",&a[i][j]),Ans+=a[i][j];
}
S=n*m+1; T=n*m+2;
for (int i=1;i<=n;i++) {
for (int j=1;j<=m;j++) {
if ((i+j)%2==0) add(S,(i-1)*m+j,a[i][j]); else add((i-1)*m+j,T,a[i][j]);
if ((i+j)%2==0) {
if (j<m) add((i-1)*m+j,(i-1)*m+j+1,INF);
if (i<n) add((i-1)*m+j,i*m+j,INF);
}
else {
if (j<m) add((i-1)*m+j+1,(i-1)*m+j,INF);
if (i<n) add(i*m+j,(i-1)*m+j,INF);
}
}
}
printf("%d\n",Ans-dinic());
}