双倍经验:Luogu P5089 元素周期表CF1012B Chemical table:模拟赛搬的好题,有点厉害。赛时10min码的假贪心拿了五十多分,赢。

并查集思路 1

对于此类棋盘整行整列覆盖问题,有一个通用思路:把每一行和每一列看作一个点,那么原本棋盘上的格子就可以看作是连接这些点的边。例如一个点是 \((x,y)\) ,那么我们就可以把行 \(x\) 代表的点与列 \(y\) 代表的点连一条边。

这样做的原因是如果确定了行与列,那么我们就可以确定唯一的点。并且本题还是整行整列地进行覆盖的,数据范围较大,只能通过此类表达方式来把原来 \(10^{12}\) 级别的点,化为 \(10^{12}\) 级别的边;剩下点的个数就为 \(2 \times 10^6\) 级别。

一些这种图的性质:

  • 如果第 \(i\) 行与第 \(j\) 列联通,可以当成格子 \((i,j)\) 处有一个点。
  • 本质上是把每个已有的格子,从横纵两个方向散开直线,这些直线只要形成交点,就是一个连通块。在本题中这么应用,是因为只要有 \(3\) 个点,我们就可以确定一个矩形。

接下来思考核聚变的过程:

对于点 \((x_1,y_1),(x_1,y_2),(x_2,y_1),(x_2,y_2)\) 组成一个矩形 ,我们先假设 \((x_2,y_2)\) 还没有生成。

那么连出的图就长这样:(圆表示 \(x\) ,方表示 \(y\) 。)

可以发现,点 \(x_2\) 与点 \(y_2\) 已经是联通的了,并且由于上述的第一条性质:如果第 \(i\) 行与第 \(j\) 列联通,可以当成格子 \((i,j)\) 处有一个点。此时的点已经自动被拓展了出来。

于是,我们只需要把 \(n+m\) 个所有的点都合并成一个连通块,就可以了。

这个过程可以用并查集维护。

合并的次数就是连通块的个数 \(-1\) 。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m,q,f[2000005],ans=0;
void init()
{
for(int i=1;i<=n+m;i++)f[i]=i;
}
int findf(int x)
{
if(f[x]!=x)f[x]=findf(f[x]);
return f[x];
}
void combine(int x,int y)
{
int fx=findf(x),fy=findf(y);
f[fx]=fy;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>q;
init();
while(q--)
{
int x,y;
cin>>x>>y;
combine(x,y+n);
}
for(int i=1;i<=n+m;i++)
{
ans+=(findf(i)==i);
}
cout<<ans-1;
return 0;
}

并查集思路 2

某位金钩爷的做法,有点复杂,但也好理解。这种做法是单纯从本题的生成点的性质入手,而上一种做法就是单纯从套路上入手。

首先我们画个图:

可以发现,如果相邻两行的同一列有棋子(蓝色部分),那么这两行就完全同步状态了。例如我们往第一行加上一些绿色点,那么我们下面的紫色部分也会加上一些点。他们的状态是完全同步的。

进一步拓展结论,就可以得到如果任意两行的同一列有棋子,那么这两行就同步状态了,所以他们就成连通块了。

最终我们拓展完后,一定会形成一些没有相同列的连通块。

于是我们一开始就把行看成点,对有相同列的进行合并,统计连通块个数(空行不能和空行算一个连通块)。

然后特判一下有没有空列,答案就是连通块个数 \(-1\) 加上空列个数。

比上一种好理解一点。代码就不写了,我懒。

二分图思路

和并查集思路 1 的做法差不多,把二分图分成上面行一部分,下面列一部分,然后照常合并。

然后遇到不连通的部分合并一下,统计一下就好了。基本和并查集一样。

代码就不写了,我懒。*2

Luogu P5089 元素周期表 / Codeforces 1012B Chemical table 题解 [ 并查集 ] [ 二分图 ] [ 图论建模 ] [ 棋盘覆盖问题 ]的更多相关文章

  1. Codeforces 1012B Chemical table (思维+二分图)

    <题目链接> 题目大意:给定一个n*m的矩阵网格,向其中加点,对于一个组成矩形的四个点中如果有三个点中有元素,那么第四个点中会自动产生新的元素.问你最少再加多少个点能够填满这个网格.解题分 ...

  2. Codeforces Round #345 (Div. 2) E. Table Compression 并查集

    E. Table Compression 题目连接: http://www.codeforces.com/contest/651/problem/E Description Little Petya ...

  3. Codeforces Round #345 (Div. 2) E. Table Compression 并查集+智商题

    E. Table Compression time limit per test 4 seconds memory limit per test 256 megabytes input standar ...

  4. Codeforces Round #345 (Div. 1) C. Table Compression (并查集)

    Little Petya is now fond of data compression algorithms. He has already studied gz, bz, zip algorith ...

  5. Codeforces 859E Desk Disorder:并查集【两个属性二选一】

    题目链接:http://codeforces.com/problemset/problem/859/E 题意: 有n个人,2n个座位. 给出这n个人初始的座位,和他们想坐的座位. 每个人要么坐在原来的 ...

  6. codeforces 456 E. Civilization(并查集+数的直径)

    题目链接:http://codeforces.com/contest/456/problem/E 题意:给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种: 1 x,输出x所在的联通块的最 ...

  7. CodeForces - 1209D Cow and Snacks 并查集

    CodeForces - 1209D 题意 现在n种点心,每种点心只有一份,有k位客人,每位客人有两种想要吃的点心,你可以安排他们进场的顺序,每位客人会吃掉所有他想要吃的,并且还没被吃掉的点心.如果客 ...

  8. Codeforces 699D Fix a Tree 并查集

    原题:http://codeforces.com/contest/699/problem/D 题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林.这些从属关系中会有两种环,第一种 ...

  9. Codeforces 731C:Socks(并查集)

    http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问 ...

  10. codeforces 400D Dima and Bacteria 并查集+floyd

    题目链接:http://codeforces.com/problemset/problem/400/D 题目大意: 给定n个集合,m步操作,k个种类的细菌, 第二行给出k个数表示连续的xi个数属于i集 ...

随机推荐

  1. Echrtas 实时渲染

    1.实时曲线图 业务场景:每个时间节点产生一个数据,且时间节点间隔不固定 坐标轴配置:X轴类型设定为time,Y轴类型设定为value 数据格式:每个节点的数据都是一个数组,第一个数组为时间,第二个元 ...

  2. uni-app在微信小程序端自定义组件中样式穿透失效

    前情 uni-app是我比较喜欢的跨平台框架,它能开发小程序/H5/APP(安卓/iOS),重要的是对前端开发友好,自带的IDE让开发体验非常棒,公司项目就是主推uni-app. 坑位 最近因UI有别 ...

  3. 鸿蒙UI开发快速入门 —— part06:组件状态管理之@State装饰器

    1.说在前面的话 在前五个章节中,我们构建的页面基本都是静态的页面,如果希望构建一个动态的.有交互的界面,就需要引入"状态"的概念,以便随着用户的交互,界面随着发生变化,例如如下的 ...

  4. 痞子衡嵌入式:MCUXpresso IDE下C++源文件中嵌套定义的复合数据类型命名空间认定

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE下C++源文件中嵌套定义的复合数据类型命名空间认定. 痞子衡之前写过一篇文章 <MCUXpresso ...

  5. Flutter之GetX之路由管理

    GetX之路由管理 GetX有一套完整的路由管理,并且不需要context上下文,API非常简洁 直接导航 导航到新的页面 Get.to(NextScreen()); 返回,此方法可以用于关闭Snac ...

  6. Flutter获取当前路由信息和全局路由监听

    Flutter获取当前路由信息和全局路由监听 获取当前路由名 通过Flutter提供的方式 var routePath = ModalRoute.of(context).settings.name; ...

  7. 基于SpringMVC XML配置文件的Dubbo开发与使用

    [模块一] 首先引入Dubbo的依赖资源,这里我们使用基于SpringMVC的项目于Dubbo进行整合 先进行依赖导入. pom.xml         <!--zookeeper--> ...

  8. 【MyBatis】学习笔记04:配置文件模板

    [Mybatis]学习笔记01:连接数据库,实现增删改 [Mybatis]学习笔记02:实现简单的查 [MyBatis]学习笔记03:配置文件进一步解读(非常重要) 目录 IDEA配置模板的地方 核心 ...

  9. leetcode 05 回文字符串

    leetcode 05 回文字符串 1. 描述 给你一个字符串,找到里面最长的回文字符串 2. 事例 示例 1: 输入:s = "babad" 输出:"bab" ...

  10. Qt音视频开发13-视频解码线程基类的设计

    一.前言 这个解码线程基类的设计,是到目前为止个人觉得自己设计的最好的基类之一,当然也不是一开始就知道这样设计,没有个三五年的摸爬滚打以及社会的毒打,是想不到要这样设计的,一方面是要不断提炼各种视频类 ...