码迷,mamicode.com
首页 > 其他好文 > 详细

CodeForces 1021B. Chemical table(并查集)

时间:2020-07-11 17:34:01      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:lin   ++   printf   产生   ace   pac   +=   res   mat   

题意:给定一个n * m的矩形,每个格子有两种颜色,一开始有t个格子上是黑色。对于任意的两行两列,如果交汇的四个格子中有三个是黑色,那么第4个会被自动变成黑色。问你至少需要手动涂黑几个格子,可以使得整个矩形内的格子都变成黑色。

分析:对于三个已经涂黑的格子\((r1, c1)(r1, c2)(r2, c1)\),会产生一个\((r2, c2)\)的格子。相当于\(r1-c1-c2\)之间连了一条边,\(r2-c1\)又连了一条边,那么就会在\(r2-c2\)之间又连了一条边。我们可以看出是一个并查集问题,给每行每列一个编号,然后合并,对于一个集合来说,如果\(p[i] = i\),说明存在一个连通块,i是这个连通块的代表元素,假设我们最终得到了res个连通块,我们还需要在这些连通块涂\(res - 1\)个黑点,才能合并成一个连通块。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 400005;
int p[N];

int find(int x)
{
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
}

int main()
{
	int n, m, q;
	scanf("%d%d%d", &n, &m, &q);

	for (int i = 1; i <= n + m; ++i) p[i] = i;

	int r, c;
	for (int i = 1; i <= q; ++i)
	{
		scanf("%d%d", &r, &c);
		c += n;
		p[find(r)] = find(c);
	}

	int res = 0;
	for (int i = 1; i <= n + m; ++i)
	{
		if (p[i] == i)
			++res;
	}

	printf("%d\n", res - 1);


	return 0;
}

CodeForces 1021B. Chemical table(并查集)

标签:lin   ++   printf   产生   ace   pac   +=   res   mat   

原文地址:https://www.cnblogs.com/pixel-Teee/p/13283914.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!