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\n",Case++);
        Riep(n)
        {
            Rjep(m-1)
                printf("%d ",cap[j+n][i]+1);
            printf("%d\n",cap[m+n][i]+1);
        }
        printf("\n");
    }
    return 0;
}
时间: 2025-01-08 10:31:30

UVA-11082 Matrix Decompressing(有上下界的最大流)的相关文章

UVA 11082 - Matrix Decompressing(网络流+行列模型)

UVA 11082 - Matrix Decompressing 题目链接 题意:给定一个矩阵每行每列的和,要求现在构造一个矩阵满足元素在1-20之间,行列和满足条件 思路:行列建图,源点连到每个行,容量为和,每列连到汇点,容量为和,每行连到每列,容量20,注意这题要求的是1-20,所以可以先把所有位置-1,最后输出的时候+1即可 代码: #include <cstdio> #include <cstring> #include <queue> #include <

UVa 11082 Matrix Decompressing(最大流)

不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... ------------------------------------------------------------------------------ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vect

[题解]UVa 11082 Matrix Decompressing

开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且题目中然而并没有什么要求,所以说可以考虑思考一下这道题有木有什么"套路"之类的通法) 比如说有这么一组数据 原矩阵 1 2 3 4 7 8 9 5 6 输入 3 3 6 25 45 14 28 45 然后将每一行的和写在每一列对应的行上(很明显有问题) 6 0 0 19 0 0 20 0

UVa 11082 Matrix Decompressing (网络流)

链接:http://acm.hust.edu.cn/vjudge/problem/36866题意:对于一个R行C列的正整数矩阵(1≤R,C≤20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和.已知R,C和数组A和B,找一个满足条件的矩阵.矩阵中的元素必须是1~20之间的正整数.输入保证有解.分析:这道题主要还是考查建模能力.如何把一个矩阵模型转化成网络流模型是关键之处.首先注意到矩阵任意行或列的元素之和是不变的(设第i行元素之和为Ai′,第i列元素之和为Bi′),因此想到把矩阵的每行和

UVA - 11082 Matrix Decompressing

很经典的网络流模型,行列分别看成一个点,行和列和分别看出容量,下界是1,所以先减去1,之后在加上就好了. 前向星建图的话,打印解会比较麻烦. #include<bits/stdc++.h> using namespace std; const int maxn = 42; struct Edge { int v,cap,flow; }; vector<Edge> edges; #define PB push_back vector<int> G[maxn]; void

UVa 11082 - Matrix Decompressing(最大流)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2023 题意: 对于一个R行C列的正整数矩阵(1≤R,C≤20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和.已知R,C和数组A和B,找一个满足条件的矩阵.矩阵中的元素必须是1-20之间的正整数.输入保证有解. 分析: 首先根据Ai和Bi计算出第i行的元素之和Ai'和第i列

Uva 11082 Matrix Decompressing (最大流)

链接 : http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=36866 可以建一个类似二分图,X集合是所有行,Y集合是所有列,X->Y的容量为(1到20).建立源点连接每个X中的点,容量为该行的和.建立汇点连接Y中的点,容量为该行的列.目的是求从源点出发的流量就是容量,且必须走完所有流量并到达汇点,汇点的流量必须是源点发出的流量.这样控制路径后求出中间过程的流量各式多少. 因为题目规定了每行的和必须等于给定的数,所以从原点出发

uva 11082 Matrix Decompressing 【 最大流 】

只看题目的话~~怎么也看不出来是网络流的题目的说啊~~~~ 建图好神奇~~ 最开始不懂---后来看了一下这篇-- http://www.cnblogs.com/AOQNRMGYXLMV/p/4280727.html 建立源点 st = 0,汇点 ed = r+c 因为正整数的范围是1到20,而流量可以是0,所以先将矩阵里面的每个数减去1,到最后输出答案的时候再加上1 把每一行看做一个节点 x,编号为1到r 把每一列看做一个节点y,编号为r+1到r+c st到x连边,容量为 Ai '- c y到e

UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)

题意:知道矩阵的前i行之和,和前j列之和(任意i和j都可以).求这个矩阵.每个格子中的元素必须在1~20之间.矩阵大小上限20*20. 思路: 这么也想不到用网络流解决,这个模型很不错.假设这个矩阵的每一行是水管,每一列是水管,每行有出水口流到每一列,这样想比较好理解.然后每行的流量和每列的流量知道,就可以建图了. 建图过程,每行对应一个点,每列对应1个点,每行都可以流到每列,所以他们之间有边.我们得假设他们是如何流向的,不如设从行流向列,那么添加源点,流向每行:添加汇点,被每列汇流.容量怎么设