这道题的建模有点像神经网络的隐层和输出层的设计。把一整行/列的和当作输入/输出结点,则它们之间的每条边就是一个矩阵内的元素。
Run Time: 0.029s
#define UVa "LT11-8.11082.cpp" //Matrix Decompressing
char fileIn[30] = UVa, fileOut[30] = UVa;
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<queue>
using namespace std;
//Global Variables. Reset upon Each Case!
const int maxn = 40 + 5, INF = 1<<30;
int T, R, C;
int A[maxn], B[maxn], Ap[maxn], Bp[maxn];
/
struct Edge {
int from, to, cap, flow;
Edge(int a, int b, int c): from(a), to(b), cap(c), flow(0) {}
};
struct EdmondsKarp {
vector<Edge> edges;
vector<int> G[maxn];
int a[maxn], p[maxn];
void init() {
edges.clear();
for(int i = 0; i < maxn; i ++) G[i].clear();
}
void addEdge(int from, int to, int cap) {
edges.push_back(Edge(from, to, cap));
edges.push_back(Edge(to, from, 0));
G[from].push_back(edges.size() - 2);
G[to].push_back(edges.size() - 1);
}
int maxFlow(int s, int t) {
int flow = 0;
for(;;) {
memset(a, 0, sizeof(a));
a[s] = INF;
queue<int> q;
q.push(s);
while(!q.empty()) {
int x = q.front(); q.pop();
for(int i = 0; i < G[x].size(); i ++) {
Edge& e = edges[G[x][i]];
int y = e.to;
if(!a[y] && e.cap > e.flow) {
a[y] = min(a[x], e.cap - e.flow);
q.push(y);
p[y] = G[x][i];
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int u = t; u != s; u = edges[p[u]].from) {
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
}
flow += a[t];
}
return flow;
}
};
void init() {
cin>>R>>C;
for(int i = 0; i < R; i ++) cin>>A[i];
for(int i = 0; i < C; i ++) cin>>B[i];
for(int i = 0; i < R; i ++) {
Ap[i] = A[i] - ((i)?A[i-1]:0);
}
for(int i = 0; i < C; i ++) {
Bp[i] = B[i] - ((i)?B[i-1]:0);
}
}
void solve() {
EdmondsKarp EK;
EK.init();
int s = R+C+1, t = R+C+2;
for(int i = 0; i < R; i ++)
EK.addEdge(s, i, Ap[i]-C);
for(int i = 0; i < C; i ++)
EK.addEdge(R+i, t, Bp[i]-R);
for(int i = 0; i < R; i ++)
for(int j = 0; j < C; j ++)
EK.addEdge(i, R+j, 19);
int ans[maxn][maxn];
EK.maxFlow(s, t);
for(int i = 0; i < EK.edges.size(); i ++) {
Edge& e = EK.edges[i];
ans[e.from][e.to-R] = e.flow;
}
for(int i = 0; i < R; i ++) {
for(int j = 0; j < C; j ++)
printf("%d ", ans[i][j]+1);
printf("\n");
}
printf("\n");
}
int main() {
cin>>T;
for(int kase = 1; kase <= T; kase ++) {
printf("Matrix %d\n", kase);
init();
solve();
}
return 0;
}