eJOI2018 Problem D Chemical table(二分图+并查集)

eJOI2018 Problem D Chemical table

题目大意

  • n ∗ m n*m nm矩阵中已有若干点,只要有构成矩形(平行于坐标轴)的四个点中三个,就可以补充剩下一个,求把矩阵填满最少需要添加多少点。
  • n , m ≤ 2 ∗ 1 0 5 n,m\le2*10^5 n,m2105

题解

  • 把行和列拆开看成二分图,发现每次添加点的操作,是在已经连通的三个点中把没连的边给连上,连通块的数量没有改变。
  • 同时,不难发现任何一个连通块中剩下的边都是可以直接加上的。
  • 现在需要把矩阵中所有点都填满,相当于所有的边都要连上,那么根据上面的结论,只需要加入最少的边使所有的点构成一个连通块即可,自然答案是连通块数量减 1 1 1

代码

#include<cstdio>
using namespace std;
int f[400010];
int get(int x) {
	if(f[x] == x) return x;
	return f[x] = get(f[x]);
}
int main() {
	int n, m, q, i, x, y;
	scanf("%d%d%d", &n, &m, &q);
	for(i = 1; i <= n + m; i++) f[i] = i;
	for(i = 1; i <= q; i++) {
		scanf("%d%d", &x, &y);
		x = get(x), y = get(y + n);
		f[x] = y;
	}
	int s = 0;
	for(i = 1; i <= n + m; i++) if(get(i) == i) s++;
	printf("%d", s - 1);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值