題意是已知一個矩陣的行數和列數和前i行的和還有前j列的和, 矩陣每個元素的值都介於1~20要求構造出這個矩陣,將每一行看成一個點, 每一列看成一個點, 源點和行相連容量爲該行的和, 每個列的點和匯點相連容量爲該列的和, 每個行和每個列也相連容量爲20, 行和列形成一個完全二分圖的結構, 對應的行連到對應的列的流量即爲該行該列的數值, 由於每個數要大於1所以實現時每條弧的容量還要減去某一個值, 詳見代碼。
#include <iostream>
#include <string>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <algorithm>
using namespace std;
const int N = 505;
const int M = 12005;
const int INF = 1000000000;
int res[N][N];
typedef int LL;
struct Dinic {
struct Edge {
int v;
LL cap, flow;
Edge* next, * pair;
void init(int a, LL b, Edge* e1, Edge* e2) {
v = a, cap = b, flow = 0, next = e1, pair = e2;
}
};
Edge* head[N], * used[N];
Edge* it;
int lev[N], que[N];
Edge E[M];
int n, s, t;
LL maxFlow;
void init(int n, int s, int t) {
it = E;
this->n = n;
this->s = s, this->t = t;
for (int i = 0; i < n; i++)
head[i] = 0;
}
void add(int u, int v, LL c) {
it->init(v, c, head[u], it + 1);
head[u] = it++;
it->init(u, 0, head[v], it - 1);
head[v] = it++;
}
bool bfs() {
for (int i = 0; i < n; lev[i++] = -1);
lev[s] = 0;
int st = 0, ed = 0;
que[ed++] = s;
while (st < ed) {
int u = que[st++];
for (Edge* e = head[u]; e; e = e->next) {
int v = e->v;
if (lev[v] == -1 && e->cap > e->flow) {
lev[v] = lev[u] + 1;
que[ed++] = v;
}
}
}
return lev[t] != -1;
}
LL dfs(int u, LL f) {
if (u == t) return f;
for (Edge* & e = used[u]; e; e = e->next) {
int v = e->v;
if (e->cap > e->flow && lev[v] == lev[u] + 1) {
LL tmp = dfs(v, min(e->cap - e->flow, f));
if (tmp > 0) {
e->flow += tmp;
e->pair->flow -= tmp;
return tmp;
}
}
}
return 0;
}
void run() {
maxFlow = 0;
while (bfs()) {
for (int i = 0; i < n; i++)
used[i] = head[i];
LL f = 1;
while (f) {
f = dfs(s, INF);
maxFlow += f;
}
}
}
void solve(int r) {
for (int u = 1; u <= r; u++) {
for (Edge* e = head[u]; e; e = e->next) {
if (e->v > r) {
res[u][e->v - r] = e->flow + 1;
}
}
}
}
}G;
int main() {
int i,j, r, c;
int T;
scanf("%d",&T);
int test=0;
while(T--)
{
scanf("%d %d",&r,&c);
int s,t;
s=0,t=r+c+1;
G.init(t + 1, s, t);
int pre=0;
for(i=1; i<=r; i++)
{
int temp;
scanf("%d",&temp);
G.add(s,i,temp-pre-c);
for(j=1; j<=c; j++)
{
G.add(i,r+j,19);
}
pre=temp;
}
pre=0;
for(i=1; i<=c; i++)
{
int temp;
scanf("%d",&temp);
G.add(r+i,t,temp-pre-r);
pre=temp;
}
printf("Matrix %d\n",++test);
G.run();
G.solve(r);
for (i = 1; i <= r; i++) {
for (j = 1; j <= c - 1; j++)
printf("%d ", res[i][j]);
printf("%d\n", res[i][c]);
}
puts("");
}
return 0;
}