题意:

给定一个H行W列的矩阵,在矩阵的格点上放带权值的卡片(一个点上能放多张)。

现在从每行每列各拿走一张卡片(没有可以不拿),求可以拿到的最大权值。

卡片数N<=1e5,H,W<=1e5

思路:

显然可以构造成一个最大费用流模型:每张卡片到它对应的行列各有一条费用0,容量1的边;源点到每张卡片有一条费用为卡片权值,容量1的边;每个行列到汇点有一条费用0,容量1的边。但是边数有5e5,应该会超时吧?

观察这个图发现除去源点和汇点是一张二分图,想到是否可以利用二分图的性质简化问题。

手动模拟一波发现好像只要贪心地从大到小拿,能拿则拿,那么就能得到最佳答案。如何检测是否还能拿呢?

HALL定理:如果一个二分图上,左部|X|<=右部|Y|,如果左部点的任意一个子集U,U相连边对应右部的子集V都有|U|<=|V|,那么这个二分图有最大匹配|X|。

每次拿走点相当于在U中增加点,在V中增加边,用并查集维护一下集合的大小即可。

  1. 所在行列在同个集合中,直接判断这个集合是否满足条件
  2. 所在行列不在同一个集合中,那么判断这两个集合合并后是否满足条件,若是则合并
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+5;
struct node{
int r,c,a;
friend bool operator<(node a,node b){
return a.a>b.a;
}
}st[maxn];
int fa[maxn],S[maxn],T[maxn];
int n,H,W;
int init(){
for(int i=1;i<=H+W;i++){
fa[i]=i;
T[i]=1;
}
}
int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
int main(){
cin>>n>>H>>W;
init();
for(int i=1;i<=n;i++){
scanf("%d%d%d",&st[i].r,&st[i].c,&st[i].a);
}
sort(st+1,st+1+n);
ll ans=0;
for(int i=1;i<=n;i++){
// printf("%d %d %d\n",st[i].r,st[i].c,st[i].a);
int fr=find(st[i].r),fc=find(H+st[i].c);
if(fr==fc){//两个在同一集合内
if(T[fc]>=S[fc]+1){
S[fc]++;
ans=ans+st[i].a;
}
}
else{//两个不在同一集合内,要合并
if(T[fr]+T[fc]>=S[fr]+S[fc]+1){
fa[fr]=fc;
T[fc]+=T[fr];
S[fc]=S[fr]+S[fc]+1;
ans=ans+st[i].a;
}
}
}
printf("%lld\n",ans);
}

Card Collector AtCoder - 5168(二分图匹配的HALL定理)的更多相关文章

  1. 【CF981F】Round Marriage(二分答案,二分图匹配,Hall定理)

    [CF981F]Round Marriage(二分答案,二分图匹配,Hall定理) 题面 CF 洛谷 题解 很明显需要二分. 二分之后考虑如果判定是否存在完备匹配,考虑\(Hall\)定理. 那么如果 ...

  2. 关于Hall定理的学习

    基本定义 \(Hall\) 定理是二分图匹配的相关定理 用于判断二分图是否存在完美匹配 存在完美匹配的二分图即满足最大匹配数为 \(min(|X|,|Y|)\) 的二分图,也就是至少有一边的点全部被匹 ...

  3. BZOJ1135 LYZ(POI2009) Hall定理+线段树

    做这个题之前首先要了解判定二分图有没有完备匹配的Hall定理: 那么根据Hell定理,如果任何一个X子集都能连大于等于|S|的Y子集就可以获得完备匹配,那么就是: 题目变成只要不满足上面这个条件就能得 ...

  4. loj#6062. 「2017 山东一轮集训 Day2」Pair hall定理+线段树

    题意:给出一个长度为 n的数列 a和一个长度为 m 的数列 b,求 a有多少个长度为 m的连续子数列能与 b匹配.两个数列可以匹配,当且仅当存在一种方案,使两个数列中的数可以两两配对,两个数可以配对当 ...

  5. AtCoder AGC037D Sorting a Grid (二分图匹配)

    题目链接 https://atcoder.jp/contests/agc037/tasks/agc037_d 题解 这场D题终于不像AGC032D和AGC036D一样神仙了-- 还是可做的吧 虽然考场 ...

  6. Hall定理 二分图完美匹配

    充分性证明就先咕了,因为楼主太弱了,有一部分没看懂 霍尔定理内容 二分图G中的两部分顶点组成的集合分别为X, Y(假设有\(\lvert X \rvert \leq \lvert Y \rvert\) ...

  7. @atcoder - Japanese Student Championship 2019 Qualification - E@ Card Collector

    目录 @description@ @solution@ @accepted code@ @details@ @description@ N 个卡片放在 H*W 的方格图上,第 i 张卡片的权值为 Ai ...

  8. AtCoder Regular Contest 092 C - 2D Plane 2N Points(二分图匹配)

    Problem Statement On a two-dimensional plane, there are N red points and N blue points. The coordina ...

  9. (转)二分图匹配匈牙利算法与KM算法

    匈牙利算法转自于: https://blog.csdn.net/dark_scope/article/details/8880547 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名 ...

随机推荐

  1. 洛谷 P1462 通往奥格瑞玛的道路(二分答案,堆优化dijkstra)

    传送门 解题思路 首先看题目问题,求经过的所有城市中最多的一次收取的费用的最小值是多少.一看“最大值最小”就想到了二分答案. 在读一遍题目,就是二分收取的费用,然后对于每一个二分的费用,跑一边最短路, ...

  2. Kali系统 metasploit 使用教程

    基础配置 由于kali 2.0 已经没有metasploit 这个服务了,所以service metasploit start 的方式不起作用. 在kali 2.0中启动带数据库支持的MSF方式如下: ...

  3. Sobel硬件实现的硬件代码分析(三)

    #include "xaxivdma.h" #include "xaxivdma_i.h" #include "xhls_sobel.h" ...

  4. C# <T>泛型的使用

    在定义泛型类时,可以对客户端代码能够在实例化类时用于类型参数的类型种类施加限制.如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误.这些限制称为约束.约束是使用 where 上 ...

  5. 【JAVA】Java 异常中e的getMessage()和toString()方法的异同

    参考链接 CSDN: Java 异常中e的getMessage()和toString()方法的异同 示例代码1: public class TestInfo {     private static ...

  6. Could not load file or assembly system.data.sqlite.dll or one for it's depedencies

    最近做一个winform项目,因为数据库用的表很少,所以用的是轻量级数据库sqlite.sqlite的优点很多,但是他要分两个版本,32位或者64位,不能同时兼容. 我遇到的问题是,我在开发端用的是. ...

  7. js超简单冒泡算法

    点击按钮--从大到小排序,可以通过代码中大于号小于号的选择来判定从小到大或者从大到小. <!DOCTYPE html> <html> <head> <titl ...

  8. FCKeditor用在JSP中的几点注意事项

    转自:https://blog.csdn.net/asinzy/article/details/3854127 本篇文章主要介绍了"FCKeditor用在JSP中的几点注意事项", ...

  9. InvalidMappingException提示Could not parse mapping document错误的解决方法

    转自:http://www.itzhai.com/invalidmappingexception-could-not-parse-mapping-document-prompt-the-wrong-s ...

  10. CSS中用 opacity、visibility、display 属性将 元素隐藏 的 对比分析

    说明 opacity 用来设置透明度 display 定义建立布局时元素生成的显示框类型 visibility 用来设置元素是否可见. opacity.visibility.display 这三个属性 ...