#include <bits/stdc++.h>
#define id(i, j) ((i-1)*m+j)
#define bel(i, j) ((i&1)^(j&1))
#define pd(i, j) (i&&i<=n&&j&&j<=m)
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x){
char c=getchar();x=0;int f=1;
while(!isdigit(c))f=c=='-'?-f:f,c=getchar();
while(isdigit(c)) x=x*10+c-'0',c=getchar();x*=f;
}
const int N=100;
const ll inf=0x3f3f3f3f3f3f3f3fll;
namespace MF{
const int V=N*N, E=V<<4;
int s, t, e, d[V], head[V], cur[V], to[E], nxt[E];
ll fl[E], mxflow;
inline void init(){
e=1;
memset(head, 0, sizeof(head));
}
inline void add(int u, int v, ll w){
to[++e]=v;
fl[e]=w;
nxt[e]=head[u];
head[u]=e;
}
inline void add_path(int u, int v, ll w){
add(u, v, w);
add(v, u, 0);
}
inline bool bfs(){
static queue <int> q;
memset(d, 0, sizeof(d));
d[s]=1;
q.push(s);
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=head[u]; i; i=nxt[i]){
int v=to[i];
if(fl[i]&&!d[v]){
d[v]=d[u]+1;
q.push(v);
}
}
}
return d[t];
}
inline ll dfs(int u, ll flow){
if(u==t||!flow) return flow;
ll res=flow;
for(int &i=cur[u]; i; i=nxt[i]){
int v=to[i];
if(fl[i]&&d[v]==d[u]+1){
ll aug=dfs(v, min(res, fl[i]));
fl[i]-=aug;
fl[i^1]+=aug;
res-=aug;
if(!res) break;
}
}
return flow-res;
}
inline ll dinic(){
ll tmp=0;
mxflow=0;
while(bfs()){
memcpy(cur, head, sizeof(head));
while((tmp=dfs(s, inf)))
mxflow+=tmp;
}
return mxflow;
}
}
int T, n, m, cnt[2];
ll a[N][N], mx, sum[2];
inline bool check(int x){
static const int dx[]={1, 0, -1, 0}, dy[]={0, 1, 0, -1};
using namespace MF;
if(x<mx) return false;
init();
ll tot=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j){
int u=id(i, j);
if(bel(i, j)){
add_path(s, u, x-a[i][j]);
tot+=x-a[i][j];
for(int k=0; k<4; ++k) if(pd(i+dx[k], j+dy[k]))
add_path(u, id(i+dx[k], j+dy[k]), inf);
}
else add_path(u, t, x-a[i][j]);
}
return dinic()==tot;
}
int main(){
read(T);
int t0=0;
while(T--){
++t0;
sum[0]=sum[1]=cnt[0]=cnt[1]=mx=0;
read(n);read(m);
MF::t=n*m+1;
for(int i=1; i<=n; ++i)
for(int j=1; j<=m; ++j){
read(a[i][j]);
++cnt[bel(i, j)];
sum[bel(i, j)]+=a[i][j];
mx=max(mx, a[i][j]);
}
if((n&1)&&(m&1)){
ll x=(sum[1]-sum[0])/(cnt[1]-cnt[0]);
if(check(x)) printf("%lld\n", MF::mxflow);
else puts("-1");
}
else{
if(sum[0]!=sum[1]){
puts("-1");
continue;
}
ll l=mx, r=2e9;
while(l<r){
ll mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
check(l);
printf("%lld\n", MF::mxflow);
}
}
return 0;
}
莫名其妙爆零了,而且似乎是黑白点数不相等时候的问题。有哪位大佬可以帮忙找一下问题吗?感激不尽!