标签: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