1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
| #include <bits/stdc++.h> using namespace std; const int N = 2e3 + 5,M = 2e6 + 5; const int inf = 0x3f3f3f3f;
int n,m,cnt,K; int id[N][N]; int a[N][N],b[N][N]; int tp[M],p1[M],p2[M];
namespace Flow { int fir[N],nxt[M],to[M],w[M],cst[M],ect = 1; inline void addedge(int u1,int v1,int w1,int c1) { nxt[++ect] = fir[u1];fir[u1] = ect;to[ect] = v1;w[ect] = w1;cst[ect] = c1;tp[ect] = 0; } inline void ins(int u1,int v1,int w1,int c1) { addedge(u1,v1,w1,c1);addedge(v1,u1,0,-c1);} int dis[N],h[N],vst[N],pw[N],pe[N]; int tot; inline void Clr(int _n) { tot = _n;ect = 1; for(int i = 1;i <= tot;i++) fir[i] = h[i] = 0; } struct node { int id,dis; node(){} node(const int _id,const int _dis):id(_id),dis(_dis){} bool operator < (const node &rhs) const { return dis > rhs.dis;} }; priority_queue<node> Q; bool Dijkstra(int S,int T) { for(int i = 1;i <= tot;i++) dis[i] = 1e9,vst[i] = 0; Q.emplace(S,dis[S] = 0); while(!Q.empty()) { int x = Q.top().id;Q.pop(); if(vst[x]) continue; vst[x] = true; for(int i = fir[x],y;y = to[i],i;i = nxt[i]) if(w[i] > 0 && dis[y] > dis[x] + cst[i] + h[x] - h[y]) Q.emplace(y,dis[y] = dis[x] + cst[i] + h[x] - h[y]),pw[y] = x,pe[y] = i; } return dis[T] < 1e9; } int MCMF(int S,int T,int K) { int res = 0,D = 0,flow = 0; while(Dijkstra(S,T)) { for(int i = 1;i <= tot;i++) h[i] += dis[i]; int f = 1e9; for(int i = T;i != S;i = pw[i]) f = min(f,w[pe[i]]); if(h[T] != 0) f = min(f,D + K - flow); if(!f) break; for(int i = T;i != S;i = pw[i]) w[pe[i]] -= f,w[pe[i] ^ 1] += f; flow += f;res += h[T] * f; if(h[T] == 0) D = flow; } return res; } }
inline void work() { cin >> n >> m >> K; cnt = 0; for(int i = 0;i <= n;i++) for(int j = 1;j < m;j++) id[i][j] = ++cnt; int S = cnt + 1,T = cnt + 2;cnt += 2; Flow::Clr(cnt); for(int i = 1;i <= n;i++) for(int j = 1;j < m;j++) { cin >> a[i][j]; int u = id[i - 1][j],v = id[i][j]; Flow::ins(u,v,a[i][j],0); Flow::ins(u,v,inf,1); tp[Flow::ect] = 1;p1[Flow::ect] = i;p2[Flow::ect] = j; Flow::ins(v,u,a[i][j],0); Flow::ins(v,u,inf,1); tp[Flow::ect] = 1;p1[Flow::ect] = i;p2[Flow::ect] = j; } for(int i = 1;i < n;i++) for(int j = 1;j <= m;j++) { cin >> b[i][j]; if(j == 1 || j == m) continue; int u = id[i][j - 1],v = id[i][j]; Flow::ins(u,v,b[i][j],0);Flow::ins(u,v,inf,1); tp[Flow::ect] = 2;p1[Flow::ect] = i;p2[Flow::ect] = j; Flow::ins(v,u,b[i][j],0);Flow::ins(v,u,inf,1); tp[Flow::ect] = 2;p1[Flow::ect] = i;p2[Flow::ect] = j; } for(int i = 1;i < m;i++) Flow::ins(S,id[0][i],inf,0),Flow::ins(id[n][i],T,inf,0); int num = Flow::MCMF(S,T,K); cout << num << endl; for(int i = 1;i <= Flow::ect;i++) if(tp[i] > 0) { assert(Flow::w[i] >= 0); if(tp[i] == 1) a[p1[i]][p2[i]] += Flow::w[i]; else b[p1[i]][p2[i]] += Flow::w[i]; } for(int i = 1;i <= n;i++) for(int j = 1;j < m;j++) cout << a[i][j] << (j == m - 1 ? '\n' : ' '); for(int i = 1;i < n;i++) for(int j = 1;j <= m;j++) cout << b[i][j] << (j == m ? '\n' : ' '); } int main() { int T; cin >> T; while(T--) work(); return 0; }
|