UVA11082:Matrix Decompressing

题意:给定一个矩阵的前i行的和,以及前i列的和,求任意一个满足条件的矩阵,矩阵元素在[1,20]

矩阵行列<=20

题解:做一个二分图的模型,把行列拆开,然后设源点到行节点的容量就是该行所有元素的和,设汇点到列节点的容量就是该列所有元素的和

然后分别减去列数和行数,再把每个行节点和列节点之间连一条长度为19的边,这样的好处就是全部减了1,流的非负的,从而满足[1,20]

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define MAXN 220
#define INF 0x7f7f7f7f
using namespace std;
int n,m;
int a[MAXN],b[MAXN];
struct Edge{
    int from,to,cap,flow;
    Edge(int u=0,int v=0,int c=0,int f=0){
        from=u,to=v,cap=c,flow=f;
    }
};
struct Dinic{
    int n,m,s,t;
    vector<Edge> edges;
    vector<int> G[MAXN<<1];
    int b[MAXN<<1];
    int d[MAXN<<1];
    int cur[MAXN<<1];
    void init(int n,int s,int t){
        this->n=n;
        this->s=s,this->t=t;
        edges.clear();
        for(int i=0;i<=n;i++){
            G[i].clear();
        }
    }
    void AddEdge(int x,int y,int cap){
        edges.push_back(Edge(x,y,cap,0));
        edges.push_back(Edge(y,x,0,0));
        m=edges.size();
        G[x].push_back(m-2);
        G[y].push_back(m-1);
    }
    bool BFS(){
        memset(b,0,sizeof(b));
        queue<int> q;
        d[s]=1;
        q.push(s);
        b[s]=1;
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=0;i<G[x].size();i++){
                Edge& e=edges[G[x][i]];
                if(e.cap>e.flow&&!b[e.to]){
                    d[e.to]=d[x]+1;
                    q.push(e.to);
                    b[e.to]=1;
                }
            }
        }
        return b[t];
    }
    int dfs(int x,int a){
        if(x==t||!a)return a;
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++){
            Edge& e=edges[G[x][i]];
            if(d[e.to]==d[x]+1&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0){
                edges[G[x][i]].flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(!a){
                    break;
                }
            }
        }
        return flow;
    }
    int Maxflow(){
        int flow=0;
        while(BFS()){
            memset(cur,0,sizeof(cur));
            flow+=dfs(s,INF);
        }
        return flow;
    }
}D;
void init(){
    scanf("%d%d",&n,&m);
    D.init(n+m+1,0,n+m+1);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=m;i++){
        scanf("%d",&b[i]);
    }
    for(int i=n;i>=1;i--){
        a[i]-=a[i-1];
    }
    for(int i=m;i>=1;i--){
        b[i]-=b[i-1];
    }    
    for(int i=1;i<=n;i++){
        D.AddEdge(0,i,a[i]-m);
    }
    for(int i=1;i<=m;i++){
        D.AddEdge(i+n,n+m+1,b[i]-n);
    }
    for(int i=1;i<=n;i++){
        for(int j=n+1;j<=n+m;j++){
            D.AddEdge(i,j,19);
        }
    }
}
int s[MAXN][MAXN];
int T;
void solve(){
    D.Maxflow();
    for(int i=0;i<D.edges.size();i++){
        Edge& e=D.edges[i];
//        printf("%d->%d:c=%d f=%d
",e.from,e.to,e.cap,e.flow);
        if(1<=e.from&&e.from<=n&&n+1<=e.to&&e.to<=n+m){
            s[e.from][e.to-n]=e.flow+1;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<m;j++){
            printf("%d ",s[i][j]);
        }
        printf("%d
",s[i][m]);
    }
    printf("
");
}
int main()
{
//    freopen("data.in","r",stdin);
    scanf("%d",&T);
    for(int i=1;i<=T;i++){
        printf("Matrix %d
",i);
        init();
        solve();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/w-h-h/p/7843603.html