UVA-11082 Matrix Decompressing(有上下界的最大流)

题目链接:

Matrix Decompressing

 

 

题意:

给一个矩阵的每行和每列的和,(给的是前i行或者列的和);

矩阵中每个元素的值在1到20之间,找出这样的一个矩阵;

 

思路:

把它转化成一个二分图,每行和每列之间连一条弧,然后设置一个源点和一个汇点,源点与行点相连,汇点与列点相连,求一个最大值,当然这是一个有下界的最大流,需要做-1的处理,同时与源汇相连的边也是要处理的;最后求得的反向边+1就是答案了;

 

AC代码:

 

#include <bits/stdc++.h>
/*#include <iostream>
#include <queue>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <cstdio>
*/
using namespace std;
#define Riep(n) for(int i=1;i<=n;i++)
#define Riop(n) for(int i=0;i<n;i++)
#define Rjep(n) for(int j=1;j<=n;j++)
#define Rjop(n) for(int j=0;j<n;j++)
#define mst(ss,b) memset(ss,b,sizeof(ss));
typedef long long LL;
const LL mod=1e9+7;
const double PI=acos(-1.0);
const int inf=0x3f3f3f3f;
const int N=1e5+25;

int n,m,a[45],b[45],cap[45][45],path[45],flow[45];
queue<int>qu;
int bfs()
{
    mst(path,-1);
    flow[0]=inf;
    path[0]=0;
    qu.push(0);
    while(!qu.empty())
    {
        int fr=qu.front();
        qu.pop();
        for(int i=1;i<=n+m+1;i++)
        {
            if(path[i]==-1&&cap[fr][i])
            {
                flow[i]=min(cap[fr][i],flow[fr]);
                path[i]=fr;
                qu.push(i);
            }
        }
    }
    if(path[n+m+1]==-1)return -1;
    return flow[n+m+1];
}
void maxflow()
{
    int now,pre;
    while(1)
    {
        int temp=bfs();
        if(temp==-1)break;
        now=n+m+1;
        while(now!=0)
        {
            pre=path[now];
            cap[pre][now]-=temp;
            cap[now][pre]+=temp;
            now=pre;
        }
    }
}
int main()
{
    int t,Case=1;
    scanf("%d",&t);
    while(Case<=t)
    {
        mst(cap,0);
        scanf("%d%d",&n,&m);
        Riep(n)scanf("%d",&a[i]);
        Riep(n)
        {
            cap[0][i]=a[i]-a[i-1]-m;
        }
        Riep(m)scanf("%d",&b[i]);
        Riep(m)
        {
           cap[i+n][n+m+1]=b[i]-b[i-1]-n;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                cap[i][j+n]=19;
        maxflow();
        printf("Matrix %d
",Case++);
        Riep(n)
        {
            Rjep(m-1)
                printf("%d ",cap[j+n][i]+1);
            printf("%d
",cap[m+n][i]+1);
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhangchengc919/p/5487916.html