@atcoder - Japanese Student Championship 2019 Qualification - E@ Card Collector
@description@
N 个卡片放在 H*W 的方格图上,第 i 张卡片的权值为 Ai,放在 (Ri, Ci)。一个位置可以放置多张卡片。
你可以在每行捡起最多一张卡片,然后在每列捡起最多一张卡片。
求捡起的卡片权值最大和。
Constraints
所有值都是整数。
1≤N≤10^5, 1≤H,W≤10^5, 1≤Ai≤10^5, 1≤Ri≤H, 1≤Ci≤W。
Input
输入的形式如下:
N H W
R1 C1 A1
R2 C2 A2
⋮
⋮
RN CN AN
Output
输出可能的最大权和。
Sample Input
6 2 2
2 2 2
1 1 8
1 1 5
1 2 9
1 2 7
2 1 4
Sample Output
28
样例解释如下:
从第一行捡起第四张卡 A4。
从第二行捡起第六张卡 A6。
从第三行捡起第二张卡 A2。
从第四行捡起第五张卡 A5。
最后权值和 = A4 + A6 + A2 + A5 = 9 + 7 + 4 + 8 = 28。
@solution@
看到这个题就知道它一定是个网络流。
我们源点连向每个卡片,容量为 1,费用为权值;卡片连向它所在的行与列,容量为 1,费用为 0;每行每列向汇点连边,容量为 1,费用为 0。
这样建图跑出来的最大费用流就是答案。
观察这个建图,思考发现它总是先沿着卡片权值最大的路径尝试增广,且它的增广过程是不会撤回的(即以前增广过的卡片不会在某一次增广中被删掉)。
所以:我们可以考虑按权值从大到小加入每张卡片,判断每次加入的卡片是否能与之前的卡片共存。
考虑我们建出来的图实际上一个二分图,我们可以使用 hall 定理判定每次加入卡片后,图中是否依然存在完美匹配。
回想 hall 定理的内容:一个点集 S 的 size <= 它邻集 T 的 size,也可以写作 |T| - |S| >= 0。我们这里的点集的邻集就代表它们所在的行列集合。
我们尝试去找不满足 hall 定理的情况。
假如仅存在单独一个点,则 |T| - |S| = 1。如果加入一个与它不在同一行或同列的点,此时 |T| - |S| 会变大,与我们目的相悖;加入一个与它在同一行或同一列的点时,|T| - |S| 不变,但之后加入的点更有可能使得 |T| - |S| 变小,所以加入这个点更有可能不满足 hall 定理。
于是:我们通过找这个点集同一行同一列的所有点不断扩大点集,到无法扩大时再判断此时的 |T| - |S| 是否满足 hall 定理。
具体到实现,我们可以对行与列建并查集,并查集内统计这个行列集合含多少行多少列(即上文的 |T|)与这些行列上有多少卡片(即上文的 |S|)。
每次加入一张卡片就把它所在的行列集合通过并查集合并,同时维护一下。当然要在加入之前判断是否合法(即是否加入完这张卡片,它所在的集合会出现 |T| - |S| < 0)。
@accepted code@
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN = 100000;
struct node{
int R, C, A;
friend bool operator < (node a, node b) {
return a.A < b.A;
}
}nd[MAXN + 5];
int fa[2*MAXN + 5], key[2*MAXN + 5], siz[2*MAXN + 5];
int find(int x) {
return fa[x] = (fa[x] == x ? x : find(fa[x]));
}
int N, H, W;
int main() {
long long ans = 0;
scanf("%d%d%d", &N, &H, &W);
for(int i=1;i<=H;i++) fa[i] = i, siz[i] = 1, key[i] = 0;
for(int i=1;i<=W;i++) fa[i + H] = i + H, siz[i + H] = 1, key[i + H] = 0;
for(int i=1;i<=N;i++)
scanf("%d%d%d", &nd[i].R, &nd[i].C, &nd[i].A);
sort(nd + 1, nd + N + 1);
for(int i=N;i>=1;i--) {
int fx = find(nd[i].R), fy = find(nd[i].C + H);
if( fx == fy ) {
if( siz[fx] >= key[fx] + 1 ) {
key[fx]++;
ans += nd[i].A;
}
}
else {
if( siz[fx] + siz[fy] >= key[fx] + key[fy] + 1 ) {
siz[fx] += siz[fy], key[fx] += key[fy] + 1, fa[fy] = fx;
ans += nd[i].A;
}
}
}
printf("%lld\n", ans);
}
@details@
被老师莫名其妙拉去打这种奇怪的比赛。。。
在我印象里,现在 hall 定理的题还是算比较少的吧,记下来记下来。
@atcoder - Japanese Student Championship 2019 Qualification - E@ Card Collector的更多相关文章
- @atcoder - Japanese Student Championship 2019 Qualification - F@ Candy Retribution
目录 @description@ @solution@ @accepted code@ @details@ @description@ 请找到满足以下条件的长度为 N 的非负整数序列 A1, A2, ...
- [AtCoder] NIKKEI Programming Contest 2019 (暂缺F)
[AtCoder] NIKKEI Programming Contest 2019 本来看见这一场的排名的画风比较正常就来补一下题,但是完全没有发现后两题的AC人数远少于我补的上一份AtCoder ...
- [AtCoder] Yahoo Programming Contest 2019
[AtCoder] Yahoo Programming Contest 2019 很遗憾错过了一场 AtCoder .听说这场是涨分场呢,于是特意来补一下题. A - Anti-Adjacency ...
- HDOJ 4336 Card Collector
容斥原理+状压 Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 4336:Card Collector(容斥原理)
http://acm.split.hdu.edu.cn/showproblem.php?pid=4336 Card Collector Special Judge Problem Descriptio ...
- Card Collector(HDU 4336)
Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu4336 Card Collector 状态压缩dp
Card Collector Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 4336 Card Collector(动态规划-概率DP)
Card Collector Problem Description In your childhood, do you crazy for collecting the beautiful card ...
- HDU 4336 Card Collector 期望dp+状压
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4336 Card Collector Time Limit: 2000/1000 MS (Java/O ...
随机推荐
- CSS的color属性并非只能用于文本显示
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过. 对于CSS的color属性,相信所有Web开发人员都使用过 ...
- 备忘录模式(Memento、Originator、Caretaker)(状态保存,备份恢复)
定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样就可以将该对象恢复到原先保存的状态 类型:行为类 类图: 我们在编程的时候,经常需要保存对象的中间状态,当需要的时 ...
- 2019.9.21 csp-s模拟测试49 反思总结
没赶上昨天的考试,不过我这种人考不考都没有多少提升吧. 挺服气的一场考试,有生以来参加的最让人想笑的考试. T1:养花 取模,区间询问最大值,有点套路化的预处理答案…难点也在预处理上.容易想到分块然后 ...
- 云原生交付加速!容器镜像服务企业版支持 Helm Chart
2018 年 6 月,Helm 正式加入了 CNCF 孵化项目:2018 年 8 月,据 CNCF 的调研表明,有百分之六十八的开发者选择了 Helm 作为其应用包装方案:2019 年 6 月,阿里云 ...
- 阿里云DMS发布数据库网关服务: 打通网络限制 开启数据库统一管理的万能钥匙
概述 阿里云数据管理DMS在云端可提供专业的数据库服务,除对标本地数据库软件的基础功能外,还包含性能诊断.数据追踪.跨实例SQL查询(含异构数据库类型之间)等专业性功能,同时提供审计安全和企业级数据库 ...
- Scrollerview与listview或者gridview发生冲突
滑动冲突说实在的就是子view的滑动事件与父view的滑动事件的监听都在同时触发,而导致的activity的点击事件或者布局出问题 常见的就有Scrollerview与Scrollerview与lis ...
- JDK8 Stream 数据流效率分析
JDK8 Stream 数据流效率分析 Stream 是Java SE 8类库中新增的关键抽象,它被定义于 java.util.stream (这个包里有若干流类型: Stream<T> ...
- OSGi教程:Resource API Specification
此教程基于OSGi Core Release 7 OSGi Resource API规范 详细内容上面英文教程有详细解答 下面主要是一些个人见解,若有不当之处,欢迎指出: Resource:就是能够被 ...
- The 16th UESTC Programming Contest Final 游记
心情不好来写博客. 为了满足ykk想要气球的愿望,NicoDafaGood.Achen和我成功去神大耍了一圈. 因为队名一开始是LargeDumpling应援会,然后队名被和谐,变成了学校的名字,顿时 ...
- 自己动手写js分享插件 [支持https] (QQ空间,微信,新浪微博。。。)
转载:https://blog.csdn.net/libin_1/article/details/52424340 废话不多说,传送门:http://download.csdn.net/detail/ ...