Luogu P5089 元素周期表 / Codeforces 1012B Chemical table 题解 [ 并查集 ] [ 二分图 ] [ 图论建模 ] [ 棋盘覆盖问题 ]
双倍经验: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 题解 [ 并查集 ] [ 二分图 ] [ 图论建模 ] [ 棋盘覆盖问题 ]的更多相关文章
- Codeforces 1012B Chemical table (思维+二分图)
<题目链接> 题目大意:给定一个n*m的矩阵网格,向其中加点,对于一个组成矩形的四个点中如果有三个点中有元素,那么第四个点中会自动产生新的元素.问你最少再加多少个点能够填满这个网格.解题分 ...
- Codeforces Round #345 (Div. 2) E. Table Compression 并查集
E. Table Compression 题目连接: http://www.codeforces.com/contest/651/problem/E Description Little Petya ...
- 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 ...
- 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 ...
- Codeforces 859E Desk Disorder:并查集【两个属性二选一】
题目链接:http://codeforces.com/problemset/problem/859/E 题意: 有n个人,2n个座位. 给出这n个人初始的座位,和他们想坐的座位. 每个人要么坐在原来的 ...
- codeforces 456 E. Civilization(并查集+数的直径)
题目链接:http://codeforces.com/contest/456/problem/E 题意:给出N个点,M条边,组成无环图(树),给出Q个操作,操作有两种: 1 x,输出x所在的联通块的最 ...
- CodeForces - 1209D Cow and Snacks 并查集
CodeForces - 1209D 题意 现在n种点心,每种点心只有一份,有k位客人,每位客人有两种想要吃的点心,你可以安排他们进场的顺序,每位客人会吃掉所有他想要吃的,并且还没被吃掉的点心.如果客 ...
- Codeforces 699D Fix a Tree 并查集
原题:http://codeforces.com/contest/699/problem/D 题目中所描述的从属关系,可以看作是一个一个块,可以用并查集来维护这个森林.这些从属关系中会有两种环,第一种 ...
- Codeforces 731C:Socks(并查集)
http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,m天,k个颜色,每个袜子有一个颜色,再给出m天,每天有两只袜子,每只袜子可能不同颜色,问 ...
- codeforces 400D Dima and Bacteria 并查集+floyd
题目链接:http://codeforces.com/problemset/problem/400/D 题目大意: 给定n个集合,m步操作,k个种类的细菌, 第二行给出k个数表示连续的xi个数属于i集 ...
随机推荐
- Golang常见问题汇总
在开始使用golang的时候,经常会遇到各种问题,总结在此 1.unrecognized import path "golang.org/x/.. golang 在 github 上建立了一 ...
- elementui半年选择组件
1.基于elementui开发的半年选择组件 2.调用 <el-halfyear-picker v-model="date" :size="size"&g ...
- Javascript 粘贴板
1.前言 本节讲述如何封装一个操作粘贴板的方法 原理:选中某个Dom元素(比如文本域),执行区域复制命令即可. 相关API:document.execCommand():该方法允许运行命令来操纵可编辑 ...
- 原生JS点名器,随机数
因为工作内容的需要自己琢磨了一个随机数的点名器,很早就写出了一版,今天无意间又看到了之前写的代码,还是有很多bug的,今天做了完善在这里分享给大家 <script type="text ...
- 德承工控机DX-1200 成功适配2024年6月6日发布的国产开源系统OpenEuler 24.03 LTS
基础软件双子星:欧拉系统(OpenEuler)& 鸿蒙系统(OpenHarmony),鸿蒙系统常应用在华为的手机和平板电脑上,大众也较为熟悉,是面向消费电子产品领域的系统:而欧拉系统则是面向服 ...
- manim边做边学--图形的创建与销毁
上一篇介绍了文字相关的创建和销毁动画,本篇介绍几个用于几何图形的创建和销毁动画效果类. Create:用于在场景中生成一个完整的Mobject(可渲染对象) Uncreate:是Create的逆操作, ...
- nodejs版本控制器nvm安装及简单使用
介绍:nvm是node.js的版本管理器,可以安装和切换不同版本node.js 下载:https://github.com/coreybutler/nvm-windows/releases 官网下载: ...
- CVE-2023-32233 Linux 内核 UAF 漏洞分析与利用
Linux 内核 nftable 模块在处理匿名 set 时存在 UAF. 漏洞分析 漏洞成因是 nf_tables_deactivate_set 在释放匿名 set 时没有将 set 的标记设 ...
- unsupported message type: DefaultFullHttpResponse (expected: ByteBuf, FileRegion) 原因以及解决办法
使用netty做http服务器的时候 用android链接 会出现这个错误 原因是http-aggregator顺序有问题 (ps:目前大部分国内博客都是这个排序有点坑爹): 官方文档说明:For c ...
- Unity 3D简单使用C#脚本,脚本的执行顺序
Unity3D脚本间执行顺序 Unity3D中一个场景有时候需要多个脚本,可以挂在同一物体上执行,也可以挂在不同物体上执行 那么执行顺序是怎样的?我们来测试下 在上个项目基础上,再建一个Test2脚本 ...