2. B - Matrix Decompressing

题意:定义一个R*C的正整数矩阵(1<=R,C<=20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和。

题目已知R,C和数组A,B。要找一个满足条件的矩阵。矩阵中的元素要满足(1<=X[i][j]<=20)。


思路:

根据a,b数组求出每一行的元素之和a,每一列的元素之和b 建一个源点s=0,汇点t=R+C+1

然后每一行看成一个顶点1~R,每一列看成一个顶点R+1~R+C

矩阵中每一个位置看成是一条边,比如2行3列的点,就是连接第2行和第3列的点的边。 然后从s到每一行建一条边,容量为a[i],

从每一列到t建一条边,容量为b[i] 然后每一行的点向每一列的点建边,容量为20(暂且说是20,继续看下去,20是错的,19才是对的)

这样的图的意义: 整个矩阵的和代表总的流量 从s出发,分别流向R行(所以有a1+…+a[R]=总流量)

每一行的流量会分给该行的C个元素,每一个列的顶点会从R行获得总的流量,就是该列的流量,最后流到t的总流量还是s出发的流量。

所以行的顶点和列的顶点的R*C条边流过的流量就代表矩阵中R*C个位置的值。

因为题目要求矩阵的位置的值在1~20之间,

所以R*C条边的流量应该在1~20之间,所以R*C条边的最大流量即容量就是20.

但是这样是有问题的,我们好像忽略了一个问题,如果某一条边没有流量怎么办?

某一条边流量为0的情况下,就不能满足矩阵中的元素在1~20之间了

可以先给所有的边给一个值为1的流量,这样的话条件就改成了1~19 了。

求到的最后流量值+1就是矩阵中的元素值。

解决代码:

#include<bits/stdc++.h>
#define maxn 1000
#define INF (1<<31)-1 using namespace std; struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int c,int f):
from(u),to(v),cap(c),flow(f) {}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
int d[maxn];
int cur[maxn];
bool vis[maxn]; void init(int n)
{
for (int i=0; i<n; i++)
G[i].clear();
edges.clear();
} void Addedge(int from,int to,int cap)
{
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
} bool BFS()
{
memset(vis,false,sizeof(vis));
for (int i=0; i<n; i++) d[i] = INF;
d[s] = 0; vis[s] = true; queue<int> Q;
Q.push(s);
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 (!vis[e.to] && e.cap>e.flow)
{
vis[e.to] = true;
d[e.to] = d[x]+1;
Q.push(e.to);
}
}
}
return vis[t];
} int DFS(int x,int a)
{
if (x == t || a == 0)
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)
{
e. flow += f;
edges[G[x][i]^1].flow -= f;
flow += f;
a -= f;
if (a == 0)
break;
}
}
return flow;
} bool OKA()
{
for (int i=0; i<G[s].size(); i++)
{
Edge e = edges[G[s][i]];
if (e.cap!=e.flow)
return false;
}
return true;
} bool OKB(int R,int C)
{
for (int j=R+1; j<=R+C; j++)
{
Edge& e = edges[G[j][0]];
if (e.cap!=e.flow)
return false;
}
return true;
} void Maxflow(int t,int R,int C)
{
int flow = 0;
while (BFS())
{
memset(cur,0,sizeof(cur));
flow += DFS(s,INF);
} cout<<"Matrix "<<t<<endl;
if (OKA() && OKB(R,C))
{
for (int i=1; i<=R; i++)
{
int j;
for (j=1; j<G[i].size()-1; j++)
cout<<edges[G[i][j]].flow+1<<' ';
cout<<edges[G[i][j]].flow+1<<endl;
}
}
cout<<endl;
}
}; int main()
{
Dinic aa;
int T,R,C,tmp;
int a[30],b[30],c[30],d[30];
#ifndef ONLINE_JUDGE
freopen("1.in", "r", stdin);
freopen("1.out", "w", stdout);
#endif
cin>>T;
tmp = T;
while (T>0)
{
T--;
aa.init(maxn);
cin>>R>>C;
for (int i=1; i<=R; i++) cin>>a[i];
for (int i=1; i<=C; i++) cin>>b[i];
for (int i=1; i<=R; i++) c[i] = a[i]-a[i-1]-C;
for (int i=1; i<=C; i++) d[i] = b[i]-b[i-1]-R; for (int i=1; i<=R; i++)
aa.Addedge(0,i,c[i]);
for (int i=1; i<=C; i++)
aa.Addedge(R+i,R+C+1,d[i]);
for (int i=1; i<=R; i++)
for (int j=1; j<=C; j++)
aa.Addedge(i,R+j,19);
aa.s = 0; aa.t = R+C+1;
aa.Maxflow(tmp-T,R,C);
}
return 0;
}

UVA - 11082 Matrix Decompressing的更多相关文章

  1. UVa 11082 Matrix Decompressing(最大流)

    不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... -------------------------------------- ...

  2. [题解]UVa 11082 Matrix Decompressing

    开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且 ...

  3. UVa 11082 Matrix Decompressing - 网络流

    开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且 ...

  4. UVa 11082 - Matrix Decompressing(最大流)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

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

    题意: 知道矩阵的前i行之和,和前j列之和(任意i和j都可以).求这个矩阵.每个格子中的元素必须在1~20之间.矩阵大小上限20*20. 思路: 这么也想不到用网络流解决,这个模型很不错.假设这个矩阵 ...

  6. UVA - 11082 Matrix Decompressing(最大流+行列模型)

    题目大意:给出一个R行C列的矩阵,如今给出他的前1-R行和 && 前1-C列和,问这个矩阵原来是如何的,要求每一个元素大小在1-20之间 解题思路:将每一行连接到超级源点,容量为该行的 ...

  7. UVA - 11082 Matrix Decompressing (最大流,技巧)

    很经典的网络流模型,行编号和列编号分别看成一个点,行和列和分别看出容量,一个点(x,y)看出是一条边,边的容量下界是1,所以先减去1,之后在加上就好了. 建图的时候注意分配好编号,解从残留网络中的边找 ...

  8. uva 11082 Matrix Decompressing 【 最大流 】

    只看题目的话~~怎么也看不出来是网络流的题目的说啊~~~~ 建图好神奇~~ 最开始不懂---后来看了一下这篇-- http://www.cnblogs.com/AOQNRMGYXLMV/p/42807 ...

  9. uva Matrix Decompressing (行列模型)

    Matrix Decompressing 题目:    给出一个矩阵的前i行,前j列的和.要求你求出满足的矩阵. 矩阵的数范围在[1,20].   一開始就坑在了这里.没读细致题目. 囧...   事 ...

随机推荐

  1. git svn 报错

    删除 openjdk 时 remove 了一大堆软件. 可能由于这个原因导致使用 git svn 命令时出现类似下面的错误. sam@sam-CW65S:pics$ git svn rebase Ca ...

  2. gcc在出现错误的时候停止编译 -Wfatal-errors

    有时候我们编译一个大的项目的时候.会出现非常多错误使得屏幕堆满了非常多没用的信息.普通情况下我们须要找到首次出现错误的地方,在gcc中加入编译选项能够使编译停止在第一次出现错误的地方: $ gcc - ...

  3. 项目Alpha冲刺(团队10/10)

    项目Alpha冲刺(团队10/10) 团队名称: 云打印 作业要求: 项目Alpha冲刺(团队) 作业目标: 完成项目Alpha版本 团队队员 队员学号 队员姓名 个人博客地址 备注 22160041 ...

  4. collection 模块 双端队列

    单端队列 用于同一进程中的队列,可以叫做单进程队列. queue 遵循先进先出,先进去的必须先出来 1.先进先出: impore queue q = queue.Queue() 实例化一个对象 q.p ...

  5. CSS3 弹性盒子(Flex Box) 微信小程序图片通栏

    {{define "chkUrl"}} <!DOCTYPE html><html lang="zh-cmn-Hans"><head ...

  6. jquery.validate ajax验证

    $("#form1").validate({ rules: { ctl00$ContentPlaceHolder1$txtShopName: { remote: { type: & ...

  7. 一个简单的servlet

    1.创建一个自己的servlet文件,继承HttpServlet MyServlet.java package com.jmu.ccjoin.controller; import java.io.IO ...

  8. react源码分析

    ReactMount.render -> ReactMount._renderSubtreeIntoContainer -> ReactMount._renderNewRootCompon ...

  9. POJ3258 River Hopscotch —— 二分

    题目链接:http://poj.org/problem?id=3258 River Hopscotch Time Limit: 2000MS   Memory Limit: 65536K Total ...

  10. 通过ODC方法改善软件测试:3个案例研究

    正交缺陷分类法(ODC)是一种用于分析软件缺陷的归类方法.它可以结合软件开发过程的一系列数据分析技术,为测试组织提供了一个强大的针对开发过程和软件产品的评估方法.在本篇文章中,会列举三个案例研究来说明 ...