UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)
题意:
知道矩阵的前i行之和,和前j列之和(任意i和j都可以)。求这个矩阵。每个格子中的元素必须在1~20之间。矩阵大小上限20*20。
思路:
这么也想不到用网络流解决,这个模型很不错。假设这个矩阵的每一行是水管,每一列是水管,每行有出水口流到每一列,这样想比较好理解。然后每行的流量和每列的流量知道,就可以建图了。
建图过程,每行对应一个点,每列对应1个点,每行都可以流到每列,所以他们之间有边。我们得假设他们是如何流向的,不如设从行流向列,那么添加源点,流向每行;添加汇点,被每列汇流。容量怎么设?我们要让每行都满流就行了,那么行之和就是源点到该行的容量,同理汇点也如此。但是每行流向每列呢?注意每个格子的元素必须在1~20之间,所以把容量设为20,别让它流太多了。
注意到元素必须在1~20之间!!!那么这样增广路的话会出现有的完全0流怎么办?先将每个格子中的元素自减1,它的流下限总不会为负吧,计算完输出时再加回去不就行了。
#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=+; struct node
{
int from;
int to;
int cap;
int flow;
}edge[N]; int row[];
int col[];
int edge_cnt;
vector<int> vect[]; void add_node(int from,int to,int cap,int flow)
{
edge[edge_cnt].from=from;
edge[edge_cnt].to=to;
edge[edge_cnt].cap=cap;
edge[edge_cnt].flow=flow;
vect[from].push_back(edge_cnt);
edge_cnt++;
} void build_graph(int n,int m)
{
for(int i=; i<=n; i++) //加源点
{
add_node(, i, row[i], );
add_node(i ,, , );
} for(int i=; i<=m; i++) //汇点
{
add_node(n+i, n+m+, col[i], );
add_node(n+m+, n+i, , );
} for(int i=; i<=n; i++) //行-列
{
for(int j=; j<=m; j++)
{
add_node(i,n+j,,);
add_node(n+j, i,,);
}
}
} int flow[];
int path[];
int matrix[][]; int BFS(int s,int e)
{
deque<int> que;
que.push_back(s);
flow[s]=INF; while(!que.empty())
{
int x=que.front();
que.pop_front();
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if(!flow[e.to] && e.cap>e.flow)
{
path[e.to]=vect[x][i];
flow[e.to]=min(flow[e.from],e.cap-e.flow);
que.push_back(e.to);
}
}
if(flow[e]) return flow[e];
}
return flow[e];
} int cal(int s, int e)
{
int ans=;
while(true)
{
memset(flow,,sizeof(flow));
memset(path,,sizeof(path)); int tmp=BFS(s,e);
if(tmp==) return ans; ans+=tmp;
int ed=e;
while(ed!=s)
{
int t=path[ed];
edge[t].flow+=tmp;
edge[t^].flow-=tmp;
ed=edge[t].from;
} }
return ;
} void get_ans(int n,int m)
{
for(int i=; i<edge_cnt; i+=)
{
node e=edge[i];
if(e.to<n) continue;
matrix[e.from][e.to-n]=e.flow;
}
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
printf("%d ", matrix[i][j]+);
printf("\n");
}
} int main()
{
//freopen("input.txt", "r", stdin);
int r, c, t, k, Case=;
cin>>t;
while(t--)
{
for(int i=; i<; i++) vect[i].clear();
memset(matrix,,sizeof(matrix));
memset(row,,sizeof(row));
memset(col,,sizeof(col));
memset(edge,,sizeof(edge));
edge_cnt=; scanf("%d%d",&r,&c);
for(int i=; i<=r; i++) //行
scanf("%d",&row[i]); for(int i=; i<=c; i++) //列
scanf("%d",&col[i]); for(int i=r; i>; i--) //换成每行-c
row[i]-=row[i-]+c;//细心点
for(int i=c; i>; i--) //换成每列-r
col[i]-=col[i-]+r; printf("Matrix %d\n",++Case);
build_graph(r, c);
cal(, r+c+);
get_ans(r,c);
if(t) cout<<endl;
}
return ;
}
AC代码
UVA 11082 Matrix Decompressing 矩阵解压(最大流,经典)的更多相关文章
- UVa 11082 Matrix Decompressing(最大流)
不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... -------------------------------------- ...
- UVA - 11082 Matrix Decompressing
2. B - Matrix Decompressing 题意:定义一个R*C的正整数矩阵(1<=R,C<=20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和. 题目已知R,C和数 ...
- UVa 11082 - Matrix Decompressing(最大流)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVA - 11082 Matrix Decompressing(最大流+行列模型)
题目大意:给出一个R行C列的矩阵,如今给出他的前1-R行和 && 前1-C列和,问这个矩阵原来是如何的,要求每一个元素大小在1-20之间 解题思路:将每一行连接到超级源点,容量为该行的 ...
- UVA - 11082 Matrix Decompressing (最大流,技巧)
很经典的网络流模型,行编号和列编号分别看成一个点,行和列和分别看出容量,一个点(x,y)看出是一条边,边的容量下界是1,所以先减去1,之后在加上就好了. 建图的时候注意分配好编号,解从残留网络中的边找 ...
- uva 11082 Matrix Decompressing 【 最大流 】
只看题目的话~~怎么也看不出来是网络流的题目的说啊~~~~ 建图好神奇~~ 最开始不懂---后来看了一下这篇-- http://www.cnblogs.com/AOQNRMGYXLMV/p/42807 ...
- [题解]UVa 11082 Matrix Decompressing
开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且 ...
- UVa 11082 Matrix Decompressing - 网络流
开始眨眼一看怎么也不像是网络流的一道题,再怎么看也觉得像是搜索.不过虽然这道题数据范围很小,但也不至于搜索也是可以随随便便就可以过的.(不过这道题应该是special judge,因为一题可以多解而且 ...
- UVA 11082 矩阵解压(网络流建模)
矩阵解压 紫书P374 建模真的是挺难的,如果直接给我这题,我是想不到用网络流的,所以还应多做网路流建模,学会如何转化成网络流 还有,现在用的EK算法是比较慢的,还应去看看Dnic和ISAP,并且理解 ...
随机推荐
- Spark Streaming揭秘 Day16 数据清理机制
Spark Streaming揭秘 Day16 数据清理机制 今天主要来讲下Spark的数据清理机制,我们都知道,Spark是运行在jvm上的,虽然jvm本身就有对象的自动回收工作,但是,如果自己不进 ...
- 字符设备驱动中cdev与inode、file_operations的关系
一.cdev与inode 二.cdev与file_operations
- 怎样在自己的网站上做自动生成当前url的二维码
$todoString="www.maomii.com"; generateQRfromGoogle($todoString); /** * google api 最多4296个字 ...
- 【C++】GacLib——ListView.ViewSwitching
http://www.gaclib.net/Demos/Controls.ListView.ViewSwitching/Demo.html#FILESYSTEMINFORMATION_H
- PCB优化设计(转载)
PCB优化设计(一) 2011-04-25 11:55:36| 分类: PCB设计 目 前SMT技术已经非常成熟,并在电子产品上广泛应用,因此,电子产品设计师有必要了解SMT技术的常识和可制造性 ...
- 九、mysql触发器的概念
.所谓触发器,就是指设置好某个表的某个操作(insert ,update ,delete)时候,同时触发的一个操作: 一般用来,比如说删除文章主栏目,那么可以利用触发器删除这个文章栏目下的所有文章 . ...
- PS 颜色表大全-CMYK颜色表(2)
CMYK颜色表 编号 C M Y K R G B 16进制值 1 0 100 100 45 139 0 22 8B0016 2 0 100 100 25 178 0 31 B2001F 3 0 100 ...
- linux ssh 安装、安全设置
环境:ubuntu 12.04 一.简单安装设置 1. 安装ssh 服务器 $ sudo apt-get install openssh 2. 查看运行状态 $ service ssh statu ...
- cocos2dx-Lua中出现的问题
1,在Lua中print输出失效的问题 在main.lua中添加print=release_print :
- mysql 获取季度的第一天 本月的第一天,本周的第一天sql语句(转)
感谢:http://www.111cn.net/database/110/d45124323da8d2d87b80f78319987eda.htm 查看同主题的另一篇博客:http://blog.cs ...