以下代码点的数量开900,边的数量开6009都能过
而按照数据范围100乘100是不是至少有10000个点
#include<bits/stdc++.h>
#define ll long long
#define INF 1e12
#define E 6009
#define N 909
using namespace std;
const ll dx[5]={0,1,-1,0,0};
const ll dy[5]={0,0,0,1,-1};
ll n,m,nV,S,T;
struct Edge{
ll to,c,nxt;
} e[E];
ll edge,hd[N];
ll pre[N],flow[N];
ll id(ll x,ll y){
return (x-1)*n+y;
}
ll re(ll x){
if(x%2==1) return x+1;
else return x-1;
}
void add(ll u,ll v,ll c){
edge++;
e[edge]=(Edge){v,c,hd[u]};
hd[u]=edge;
}
bool bfs(){
fill(pre,pre+1+nV,0);
queue<ll> q;
q.push(S);
pre[S]=-1;
flow[S]=INF;
while(!q.empty()){
ll u=q.front(); q.pop();
for(ll i=hd[u];i;i=e[i].nxt){
ll v=e[i].to,c=e[i].c;
if(!c||pre[v]) continue;
q.push(v); pre[v]=i;
flow[v]=min(flow[u],c);
if(v==T) return true;
}
}
return false;
}
ll EdmondKarp(){
ll max_flow=0;
while(bfs()){
max_flow+=flow[T];
for(ll i=T;i!=S;i=e[re(pre[i])].to){
e[pre[i]].c-=flow[T];
e[re(pre[i])].c+=flow[T];
}
}
return max_flow;
}
int main(){
cin>>m>>n;
S=m*n+1; T=m*n+2; nV=T;
ll sum=0;
for(ll i=1;i<=m;i++){
for(ll j=1;j<=n;j++){
ll x; cin>>x; sum+=x;
if((i+j)&1){
add(S,id(i,j),x);
add(id(i,j),S,0);
continue;
}
add(id(i,j),T,x);
add(T,id(i,j),0);
for(ll k=1;k<=4;k++){
ll nx=dx[k]+i,ny=dy[k]+j;
if(nx<1||nx>m||ny<1||ny>n) continue;
add(id(nx,ny),id(i,j),INF);
add(id(i,j),id(nx,ny),0);
}
}
}
cout<<sum-EdmondKarp();
return 0;
}