解析
如果没有元素均要在 [0,1e6][0,1e6][0,1e6] 的条件,可以很容易的构造出一个合法解。
那么我们就要通过调整得到的解,使所有数都在合法范围内。
注意到,每次给某一行/列依次+1,-1,+1,-1…这样仍然符合要求。
让每一行/列错开,就能变成:
row:
+-+-+
-+-+-
+-+-+
-+-+-column:
-+-+-
+-+-+
-+-+-
+-+-+
这样每个格子行贡献和列贡献的符号就都是相反的,然后就可以差分约束了。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define ok debug("OK\n")
using namespace std;const int N=650;
const int M=50050;
const int mod=1e9+7;
const double eps=1e-9;inline ll read() {ll x(0),f(1);char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n,m;
int a[N][N],b[N][N],c[N],d[N],tot;
ll dis[N];
int o=1e6;
queue<int>q;
bool vis[N];
int tim[N];
struct node{int to,nxt,w;
}p[N*N*2];
int fi[N],cnt;
inline void addline(int x,int y,int w){p[++cnt]=(node){y,fi[x],w};fi[x]=cnt;
}
bool spfa(){memset(dis,0,sizeof(dis));memset(tim,0,sizeof(tim));for(int i=1;i<=tot;i++) q.push(i),vis[i]=1;while(!q.empty()){int now=q.front();q.pop();vis[now]=0;for(int i=fi[now];~i;i=p[i].nxt){int to=p[i].to;if(dis[to]<dis[now]+p[i].w){dis[to]=dis[now]+p[i].w;tim[to]++;if(!vis[to]){vis[to]=1;q.push(to);}if(tim[to]>tot) return false;}}}return true;
}
void work(){memset(a,0,sizeof(a));tot=0;memset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();for(int i=1;i<n;i++){for(int j=1;j<m;j++) b[i][j]=read();}for(int i=n-1;i>=1;i--){for(int j=m-1;j>=1;j--) a[i][j]=b[i][j]-a[i+1][j+1]-a[i+1][j]-a[i][j+1];}//for(int i=1;i<=n;i++){//for(int j=1;j<=m;j++) printf("%d ",a[i][j]);//puts("");//}for(int i=1;i<=n;i++) c[i]=++tot;for(int j=1;j<=m;j++) d[j]=++tot;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if((i+j)&1){addline(c[i],d[j],a[i][j]-o);addline(d[j],c[i],-a[i][j]);}else{ addline(c[i],d[j],-a[i][j]);addline(d[j],c[i],a[i][j]-o);}}}//for(int i=1;i<=tot;i++)// for(int j=1;j<=tot;j++) printf("%d -> %d w=%d\n",i,j,e[i][j]);if(!spfa()){puts("NO");return;}puts("YES");for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){ll add=dis[c[i]]-dis[d[j]];if((i+j)&1) a[i][j]+=add;else a[i][j]-=add;printf("%d ",a[i][j]);}puts("");}
}
int main() {
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifint T=read();while(T--) work();return 0;
}
/*
1
3 3
1000000 2000000
0 0
*/