题意:有一个N行M列的正整数矩阵,输入N个1~N行所有元素之和,以及M个1~M列所有元素之和。要求找一个满足这些条件,并且矩阵中的元素都是1~20之间的正整数的矩阵。输入保证有解,而且1≤N,M≤20。

解法:这题的图转换得极妙!(*^▽^*)   我们可以发现找到的矩阵需要满足3个条件:1.N行M列;2.各行各列的和;3.各元素的大小。再仔细阅读一次题目,发现题目中提到的2个数字相同——“20”,再想想这是不是有什么玄机。
     首先可以找到第3个条件的转化,可以用容量来限制,那么这题用网络流可以吗?如果用网络流,那对于元素大小限制就建边为容量19的,因为要求为1~20,而又有流量为0,于是我们就把“流量+1”当成 元素的大小。而第1个条件可以直接转化为 n+m 个点表示各行、列,那么第2个条件也是可以通过与源点和汇点连边处理得到的,也就是我们后面博文会提到的“多源多汇问题”。把源点连边到前 n 个点,边容量就是1~n行的元素之和 再-m,因为前面我们已经把各元素的大小转化为“流量+1”了,那么流量就是“大小-1”,每行有m个元素就是 -m 了。同理,把 n+1~n+m 的元素与汇点相连,边容量是1~M列的元素之和 -N。对于各行各列的和的具体分配就是看这 1~n 与 n+1~n+m 的点之间的边流量了,第 i 行第 j 列的元素大小就是点 i 到点 n+j 的边的反向弧的流量+1.
      成功建图之后,就跑一遍Dinic再求出矩阵就好了。ノ(^∀^●)ノ

  1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<queue>
5 #include<iostream>
6 #include<algorithm>
7 using namespace std;
8
9 const int N=25,NN=75,INF=(int)1e9;
10 int st,ed,n,m,len;
11 int last[NN],d[NN],num[N][N];
12 struct edge{int x,y,next,fl;}a[N*N*2];
13 queue <int> q;
14
15 int mmin(int x,int y) {return x<y?x:y;}
16 void ins(int x,int y,int fl)
17 {
18 a[++len].x=x,a[len].y=y,a[len].fl=fl;
19 a[len].next=last[x],last[x]=len;
20 a[++len].x=y,a[len].y=x,a[len].fl=0;
21 a[len].next=last[y],last[y]=len;
22 }
23 bool bfs()
24 {
25 while (!q.empty()) q.pop();
26 memset(d,0,sizeof(d));
27 q.push(st), d[st]=1;
28 while (!q.empty())
29 {
30 int x=q.front(); q.pop();
31 for (int i=last[x];i;i=a[i].next)
32 {
33 int y=a[i].y;
34 if (d[y]||(!a[i].fl)) continue;
35 q.push(y);
36 d[y]=d[x]+1;
37 }
38 }
39 return d[ed];
40 }
41 int dfs(int x,int flow)
42 {
43 if (x==ed) return flow;
44 int sum=0;
45 for (int i=last[x];i;i=a[i].next)
46 {
47 int y=a[i].y;
48 if (d[y]!=d[x]+1||(!a[i].fl)) continue;
49 int t=dfs(y,mmin(flow-sum, a[i].fl));
50 sum+=t;
51 a[i].fl-=t,a[i^1].fl+=t;
52 if (sum==flow) break;
53 }
54 if (!sum) d[x]=0;
55 return sum;
56 }
57 void Dinic()
58 {
59 int sum=0;
60 while (bfs()) sum+=dfs(st,INF);
61 /*for (int i=1;i<=n;i++)
62 {
63 int x=i;
64 for (int k=last[x];k;k=a[k].next)
65 {
66 int y=a[k].y;
67 if (!(y>n&&y<=n+m)) continue;
68 mat[x][y]=a[k^1].fl+1;
69 }
70 }*/
71 }
72 int main()
73 {
74 int T;
75 scanf("%d",&T);
76 for (int kase=1;kase<=T;kase++)
77 {
78 scanf("%d%d",&n,&m);
79 int x,y; st=n+m+1,ed=n+m+2;
80 len=1,y=0;
81 memset(last,0,sizeof(last));
82 for (int i=1;i<=n;i++)
83 {
84 scanf("%d",&x);
85 ins(st,i,x-y-m);//m
86 y=x;
87 }
88 y=0;
89 for (int i=1;i<=m;i++)
90 {
91 scanf("%d",&x);
92 ins(n+i,ed,x-y-n);//n
93 y=x;
94 }
95 for (int i=1;i<=n;i++)
96 for (int j=1;j<=m;j++)
97 {
98 ins(i,n+j,19);
99 num[i][j]=len;
100 //printf("%d %d %d %d\n",i,j,a[num[i][j]].x,a[num[i][j]].y);
101 }
102 Dinic();
103 printf("Matrix %d\n",kase);
104 for (int i=1;i<=n;i++)
105 {
106 for (int j=1;j<=m;j++)
107 printf("%d ",a[num[i][j]].fl+1);
108 printf("\n");
109 }
110 if (kase<T) printf("\n");
111 }
112 return 0;
113 }

【uva 11082】Matrix Decompressing(图论--网络流最大流 Dinic+拆点二分图匹配)的更多相关文章

  1. UVa 11082 Matrix Decompressing(最大流)

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

  2. UVA - 11082 Matrix Decompressing

    2. B - Matrix Decompressing 题意:定义一个R*C的正整数矩阵(1<=R,C<=20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和. 题目已知R,C和数 ...

  3. 【uva 753】A Plug for UNIX(图论--网络流最大流 Dinic)

    题意:有N个插头,M个设备和K种转换器.要求插的设备尽量多,问最少剩几个不匹配的设备. 解法:给读入的各种插头编个号,源点到设备.设备通过转换器到插头.插头到汇点各自建一条容量为1的边.跑一次最大流就 ...

  4. UVa 11082 Matrix Decompressing - 网络流

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

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

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

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

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

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

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

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

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

  9. uva 11082 Matrix Decompressing 【 最大流 】

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

随机推荐

  1. STM32 HAL库之串口详细篇

    一.基础认识 (一) 并行通信 原理:数据的各个位同时传输 优点:速度快 缺点:占用引脚资源多,通常工作时有多条数据线进行数据传输 8bit数据传输典型连接图: 传输的数据是二进制:11101010, ...

  2. CTF常见编码及加解密(超全)

    @ 目录 前言 常见CTF编码及加解密 补充 ASCII编码 base家族编码 MD5.SHA1.HMAC.NTLM等类似加密型 1.MD5 2.SHA1 3.HMAC 4.NTLM 5.类似加密穷举 ...

  3. Memcached repcached 高可用

    Memcached + repcached 高可用环境 repcached 就是一个让memcached的机器能够互为主从,前端可以加一台HAProxy,后端两台memcached互为主从后,写入任何 ...

  4. python学习笔记 | macOS Big Sur动态壁纸食用指南

    目录 前言 爬虫篇 壁纸使用篇 后记 前言 北京时间23日凌晨1点,苹果WWDC2020大会开幕.在发布会上,苹果正式发布了新版macOS,并将其命名为"Big Sur". 相比于 ...

  5. 【Docker】1、 前后端分离项目 下载启动运行

    人人开源前后端分离项目下载与配置 文章目录 人人开源前后端分离项目下载与配置 前后端分离框架介绍 后端项目下载与配置 1.renren-fast后台项目介绍 2.开发环境搭建 3.下载后端renren ...

  6. 大文件上传FTP

    需求 将本地大文件通过浏览器上传到FTP服务器. 原有方法 将本地文件整个上传到浏览器,然后发送到node服务器,最后由node发送到FTP服务器. 存在问题 浏览器缓存有限且上传速率受网速影响,当文 ...

  7. 【一天一个知识点系列】- Redis Cluser之数据分布

    数据分布 简述 分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集 分区及限制 分区规则 常见的分区规则 顺序分区 哈希分区 ...

  8. git创建分支并关联远程分支

    1.新建本地分支: 如图,再输入你的分支名字,然后选择从哪个远程分支拉代码,如选择master 至此本地分支创建完成. 2.关联远程分支: (1).先输入git branch -vv,看看分支与远程分 ...

  9. 5V-12V输入输出的限流芯片,可调限至4.8A

    可是在输出电压模式:3.6V,5V,12V 在输出3.6V模式:输入电压范围2.5V-4.5V,输入关闭电压5V,限流最大4.8A 在输出5V模式,输入电压范围3.8V-6V,输输入过电压关闭6V,限 ...

  10. LocalDateTime、OffsetDateTime、ZonedDateTime互转,这一篇绝对喂饱你

    前言 你好,我是A哥(YourBatman). 在JSR 310日期时间体系了,一共有三个API可用于表示日期时间: LocalDateTime:本地日期时间 OffsetDateTime:带偏移量的 ...