Matrix Decompressing UVA

来源:互联网 发布:电子图书制作软件 编辑:程序博客网 时间:2024/06/05 16:29

题目链接: UVA - 11082

题目大意

一个r*c的矩阵, 给出两个数列, 矩阵内数字在范围[1, 20]之间, A[i] := 前i行的和, B[i] := 前i列的和
还原矩阵(保证有解)

思路

以每一行每一列为节点, 设置源点s, 汇点t
s向每一行连边, 容量为这一行的数字和(通过A求出) - c(行的和-列数相当与这一行每一个数字都-1, 将数字取值范围从[1, 20]变成了[0, 19], 因为网络流里最小流量为0)
每一列向t连边, 容量为这一列的数字和 - r
每一行向每一列连边, 容量为19(最大值)
最后求s-t的最大流
矩阵中i行j列 = i行->j列的流量
题目限制了每一行每一列的流量(数字和), 那我们就往每一行通入这么多流量, 再限制每一列输出的流量, 最后让最大流算法自动处理每一个路径的流量

代码

#include <bits/stdc++.h>using namespace std;const int MAXV = 100, INF = 0X3F3F3F3F;struct edge{    int to, cap, rev, flow;    edge(int To, int Cap, int Rev, int Flow)    :to(To), cap(Cap), rev(Rev), flow(Flow){}};vector<edge> G[MAXV];int iter[MAXV];int level[MAXV];int S, T;int p, n;void add_edge(int from, int to, int cap){    G[from].push_back(edge(to, cap, int(G[to].size()), 0));    G[to].push_back(edge(from, 0, int(G[from].size()-1), 0));}bool bfs(){    memset(level, -1, sizeof(level));    queue<int> que;    level[S] = 0;    que.push(S);    while(!que.empty())    {        int v = que.front(); que.pop();        for(int i=0; i<(int)G[v].size(); ++i)        {            edge & e  = G[v][i];            if(level[e.to]<0 && e.cap > e.flow)            {                level[e.to] = level[v] + 1;                que.push(e.to);            }        }    }    return level[T] != -1;}int dfs(int v, int f){    if(v == T) return f;    for(int &i=iter[v]; i<(int)G[v].size(); ++i)    {        edge &e = G[v][i];        if(e.cap>e.flow && level[e.to]>level[v])        {            int d = dfs(e.to, min(f, e.cap-e.flow));            if(d)            {                e.flow += d;                G[e.to][e.rev].flow -= d;                return d;            }        }    }    return 0;}int max_flow(){    int flow = 0;    while(bfs())    {        memset(iter, 0, sizeof(iter));        int f;        while((f=dfs(S, INF))) flow += f;    }    return flow;}const int MAXN = 30;int r, c, a[MAXN], b[MAXN];int main(){    int t;    cin >> t;    for(int cas=1; cas<=t; ++cas)    {        for(int i=0; i<MAXV; ++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-1];        for(int i=c-1; i>0; --i) b[i] -= b[i-1];        S = 0;        T = r+c+1;        for(int i=0; i<r; ++i)        {            for(int j=0; j<c; ++j)            {                add_edge(i+1, r+1+j, 19);            }        }        for(int i=0; i<r; ++i) add_edge(S, 1+i, a[i]-c);        for(int i=0; i<c; ++i) add_edge(r+1+i, T, b[i]-r);        max_flow();        cout << "Matrix " << cas << endl;        for(int i=1; i<=r; ++i)        {            for(int j=0; j<c; ++j)            {                cout << G[i][j].flow+1 << (j==c-1 ? '\n' : ' ');            }        }    }    return 0;}
原创粉丝点击