Matrix Decompressing UVA

来源:互联网 发布:网络发帖推广怎么发 编辑:程序博客网 时间:2024/05/23 21:09

还是关于网络流的算法题,将每行以及每列之和首先计算出来,然后让矩阵中的每个数字都减少1,那么对于一个R*C的矩阵而言,反应到每行之和就是每行之和都减少C,反应到每列之和就是每列之和都减少R。之所以要减少1也就是便于后面的网络流算法的应用,也就是可以出现边的流量为零的情形。然后建立起始点和终点,起始点到R个点,每条边的容量对应每行之和,建立C个点到终点的边,每一条边的容量也就对应着列之和。然后将R个点以及C个点相互之间建立映射关系,对应的边的容量也就是最大的值19,每一条边其实也就对应着矩阵中的每一个位置,然后利用网络流算法求出最终的结果即可,具体实现见如下代码:

#include<iostream>#include<vector>#include<string>#include<set>#include<stack>#include<queue>#include<map>#include<algorithm>#include<cmath>#include<iomanip>#include<cstring>#include<sstream>#include<cstdio>#include<deque>#include<functional>using namespace std;const int Inf = 1 << 20;class Edge{public:int from, to, cap, flow;};class Solve{public:int R, C;int A[55],B[55];vector<Edge> edge;vector<int> G[100];int ID[55][55];void addEdge(int from,int to,int cap){Edge temp;temp.from = from, temp.to = to, temp.cap = cap, temp.flow = 0;edge.push_back(temp);Edge temp2;temp2.from = to, temp2.to = from, temp2.cap = 0, temp2.flow = 0;edge.push_back(temp2);int t = edge.size();G[from].push_back(t-2);G[to].push_back(t - 1);}void MaxFlow(int start,int e){while (true){int d[100];int parent[100];memset(d, 0, sizeof(d));d[start] = Inf;queue<int> q;q.push(start);while (!q.empty()){int id = q.front();q.pop();for (int i = 0; i < G[id].size(); i++){int ide = G[id][i];int to = edge[ide].to;if (!d[to]&&edge[ide].cap > edge[ide].flow){d[to] = min(d[id], edge[ide].cap - edge[ide].flow);parent[to] = ide;q.push(to);}}if (d[e]) break;}if (!d[e]) break;for (int i = e; i != start; i = edge[parent[i]].from){edge[parent[i]].flow += d[e];edge[parent[i] ^ 1].flow -= d[e];}}}void Init(){edge.clear();memset(ID,0,sizeof(ID));for (int i = 0; i < 100; i++) G[i].clear();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 = R - 1; i > 0; i--){A[i] = A[i] - A[i - 1] - C;}A[0] -= C;for (int i = C - 1; i > 0; i--){B[i] = B[i] - B[i - 1] - R;}B[0] -= R;for (int i = 0; i < R; i++){addEdge(0,i+1,A[i]);}for (int i = R + 1; i <= R + C; i++){addEdge(i, R + C + 1, B[i - R - 1]);}for (int i = 1; i <= R; i++){for (int j = 1; j <= C; j++){addEdge(i, j + R, 19);ID[i][j] = edge.size() - 2;}}}void Deal(){Init();MaxFlow(0,R+C+1);for (int i = 1; i <= R; i++){for (int j = 1; j <= C; j++){int ind = ID[i][j];cout << edge[ind].flow + 1<<" ";}cout << endl;}}};int main(){int T;cin >> T;Solve a;for (int i = 0; i < T;i++){cout << "Matrix " << i + 1 << endl;a.Deal();cout << endl;}return 0;}


原创粉丝点击