CF1012B Chemical table

本文介绍了一个$n imes m$的化学表格问题的解决方案,通过使用并查集算法构造完全二分图来解决最少标记问题。文章详细解释了如何将元素$(x, y)$视为二分图的一条边,并说明了标记条件如何不影响连通分量数量,从而得出答案为连通分量个数减一。

$CF1012B Chemical table

给你一个 \(n\times m\) 的矩形,一开始有 \(q\) 个格子上被标记。对于任意两行两列,如果交汇的四个格子中有三个被标记,那么第 \(4\) 个会被自动标记。问你至少需要手动标记几个格子,使得整个矩形内的格子都被标记。

\(n,\ m,\ q\leq2\times10^5\)

并查集,构造


把元素 \((x,\ y)\) 看做二分图的一条边 \((x,\ n+y)\)

目标是将它变成完全二分图

而标记其他点的条件 \((x_1,\ y_1),\ (x_1,\ y_2),\ (x_2,\ y_1)\to(x_2,\ y_2)\) 并不改变二分图中连通分量个数

所以对于二分图的某一个连通分量必定可以通过如上条件变成一个完全二分子图

所以答案即为联通所有连通分量的边数,即为 \(\verb|连通分量个数|-1\)

代码

#include <bits/stdc++.h>
using namespace std;

const int maxn = 4e5 + 10;
int n, m, q, ans, par[maxn];

int find(int x) {
  return par[x] == x ? x : par[x] = find(par[x]);
}

void unite(int x, int y) {
  if ((x = find(x)) != (y = find(y))) {
    par[x] = y, ans++;
  }
}

int main() {
  scanf("%d %d %d", &n, &m, &q);
  for (int i = 1; i <= n + m; i++) {
    par[i] = i;
  }
  while (q--) {
    int x, y;
    scanf("%d %d", &x, &y);
    unite(x, n + y);
  }
  printf("%d", n + m - ans - 1);
  return 0;
}

\(orz\ \color{black}{P}\color{red}{inkrabbit}\)

转载于:https://www.cnblogs.com/Juanzhang/p/10628504.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值