[BZOJ]4950 二分图 + 最大匹配
来源:互联网 发布:c编程发送snmptrap 编辑:程序博客网 时间:2024/04/25 11:48
4950: [Wf2017]Mission Improbable
Time Limit: 1 Sec Memory Limit: 1024 MBSubmit: 146 Solved: 70
[Submit][Status][Discuss]
Description
那是春日里一个天气晴朗的好日子,你准备去见见你的老朋友Patrick,也是你之前的犯罪同伙。Patrick在编程竞赛
上豪赌输掉了一大笔钱,所以他需要再干一票。为此他需要你的帮助,虽然你已经金盆洗手了。你刚开始很不情愿,
因为你一点也不想再回到那条老路上了,但是你觉得听一下他的计划也无伤大雅。在附近的一个仓库里有一批货物,
包含一些贵重的消费性部件,Patrick企图从中尽可能多地偷些东西出来。这意味着要找一条进去的路,弄晕安保人
员,穿过各种各样的激光射线,你懂的,都是常见的抢劫技术。然而,仓库的核心装备了一套Patrick搞不定的安保系
统。这也是他需要你帮助他的地方。这批货物被放置在一些巨大的立方体箱里,每个箱子的尺寸都是相同的。这些
箱子堆放成许多整齐的堆,每个箱子可以表示成一个三维的网格。安保系统每个小时会用三台相机对这堆货物进行
一次拍照,相机分别为:前置相机(front camera),侧置相机(side camera)和顶置相机(top camera)。前置相机的照
片显示了每一行最高的那堆箱子的高度,侧置相机显示了每一列最高的那堆箱子的高度,顶置相机显示了每个位置是
否存在一堆箱子。如果安保系统发现任何一张照片出现了变化,它会立即拉响警报。一旦 Patrick 进去了,他会确
定每堆箱子的高度并且发给你。图1显示了一种网格可能的放置,以及每台相机会得到的视图。
图 1. 网格的高度值与对应的相机视图。
图 2. 洗劫后网格可能的高度值。
Patrick想尽可能多偷走一些箱子。由于他不能弄坏安保系统,他准备重新安排剩余每堆箱子的放置,使得下一次相
机取像时会得到相同的照片,从而骗过安保系统。在上面的例子中,他可以偷走九个箱子。图2显示了一种可能的剩
余箱子的安置方案能使得安保系统认为与原安置情况相同。Patrick想请你帮他确定在保证能骗过安保系统的情况
下他最多能偷走多少个箱子。你会帮他干完这最后一票么?
Input
第一行包含两个整数r(1≤r≤100)和c(1≤n≤100),分别表示网格的行数与列数。
接下来r行,每行包含c个整数,表示对应行上每堆立方体箱的高度(箱子的数量)。
所有的高度在0到10^9之间 (含边界) 。
Output
输出在不被发现的情况下最多能偷走多少箱子。
Sample Input
样例1
5 5
1 4 0 5 2
2 1 2 0 1
0 2 3 4 4
0 3 0 3 1
1 2 2 1 1
样例2
2 3
50 20 3
20 10 3
5 5
1 4 0 5 2
2 1 2 0 1
0 2 3 4 4
0 3 0 3 1
1 2 2 1 1
样例2
2 3
50 20 3
20 10 3
Sample Output
样例1
9
样例2
30
9
样例2
30
HINT
Source
鸣谢Tangjz提供翻译
HOME Back
一开始考虑,每个不为0的位置都拿到1,然后每行每列最大值不能动。然后又考虑到,如果行列最大值相同,我们可以在他们交叉的位置放一个最大值即可,而不需要两个。因此转化成一个二分图匹配的问题。(显然不同的最大值不会互相干扰,因为之间根本不可能有边)每成功匹配到一个,就可以多拿一个最大值。
#include<stdio.h>#include<bitset>#include<cstring>using namespace std;bitset<205> vis;long long sum;int n, m, num, match[510], h[205], mp[205][205], mi[205], mj[205];struct edge{ int nxt, v;}e[100005];inline void add(int u, int v){e[++num].v = v, e[num].nxt = h[u], h[u] = num;}bool find(int u){for(int i = h[u]; i; i = e[i].nxt){int v = e[i].v;if(!vis[v]){vis[v] = true;if(!match[v] || find(match[v]))return match[v] = u;}}return false;}int main(){scanf("%d%d", &n, &m);for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j){scanf("%d", &mp[i][j]);mi[i] = max(mi[i], mp[i][j]);mj[j] = max(mj[j], mp[i][j]);if(mp[i][j]) sum += mp[i][j] - 1;}for(int i = 1; i <= n; ++i)for(int j = 1; j <= m; ++j)if(mi[i] == mj[j] && mp[i][j])add(i, j + n);for(int i = 1; i <= n; ++i)if(mi[i]) sum -= mi[i] - 1;for(int j = 1; j <= m; ++j) if(mj[j]) sum -= mj[j] - 1;for(int i = 1; i <= n; ++i){if(find(i)) sum += mi[i] - 1;vis = 0;}printf("%lld\n", sum);}
阅读全文
0 0
- [BZOJ]4950 二分图 + 最大匹配
- bzoj 4950(二分图最大匹配)
- BZOJ 4950 [Wf 2017] 二分图最大匹配 解题报告
- BZOJ 4950 Mission Improbable (二分图最大匹配)
- [BZOJ]3140 二分图最大匹配
- BZOJ 1191(二分图最大匹配)
- bzoj 4443(二分+二分图最大匹配)
- 【二分图最大匹配】[SCOI2010] 游戏 BZOJ 1854
- [二分图匹配][各种优化][BZOJ 2034]最大收益
- BZOJ 2744 HEOI2012 朋友圈 二分图最大匹配
- BZOJ 1191 HNOI2006 超级英雄Hero 二分图最大匹配
- BZOJ 3175 Tjoi2013 攻击装置 二分图最大匹配
- BZOJ 1854 SCOI 2010 游戏 二分图最大匹配
- BZOJ 1143 CTSC2008 祭祀river 二分图最大匹配
- [BZOJ 1854][SCOI 2010]游戏(二分图最大匹配)
- BZOJ 1059 矩阵游戏 (二分图最大匹配)
- BZOJ 1854 [Scoi2010]游戏 二分图最大匹配
- BZOJ 1191 [HNOI2006]超级英雄Hero 二分图最大匹配
- [POJ 3321]Apple Tree dfs序+树状数组
- 中文分词之jieba简单应用
- html 中的 header-作用与使用
- 学会这20个正则表达式,少些几千行代码!
- poj2112 二分+网络流
- [BZOJ]4950 二分图 + 最大匹配
- 解决webstorm启动索引文件卡死问题,可手动或可加载后在设置
- 我的博客第一天
- Educational Codeforces Round 19 题解
- myqsl练手
- 关于js正则表达式判断一个字符串是否是正确的有数字和小数点组成的金钱形式和 判读数值类型的正则表达式
- C++ 中的构造函数与析构函数顺序
- Tensorflow常用函数说明
- GTK实现文本翻页(dailyNote.c)