CF1013D Chemical table
Posted blogggggg
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1013D Chemical table相关的知识,希望对你有一定的参考价值。
题目链接:http://codeforces.com/contest/1013/problem/D
题目大意:
给出一个 (n imes m) 的表格,表格上有一些初始点。若有这样的三个点:((r_1, c_1), (r_1, c_2), (r_2, c_1)),则由这三个点能生成出点 ((r_2, c_2))。现问在初始点的基础上最少添加多少个点,能使得初始点和添加的点及它们生成出来的点能填满整个表格。
知识点: 并查集
解题思路:
可以将每一个点看成是将所在的行和列联系起来。如此一来,对于 ((r_1, c_1) + (r_1, c_2) + (r_2, c_1) Rightarrow (r_2, c_2)),我们可以理解为:因为 (r_1) 和 (c_1),(r_1) 和 (c_2),(r_2) 和 (c_1) 都相应地联系起来了,那么 (r_2) 和 (c_2) 也联系起来了。所以我们只要把所有的行和列都联系起来,生成出来的点就能填满整个表格。那么问题就转换成问最少建立多少联结,能将所有的行和列都联系起来。可以用并查集解决。
AC代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 #define lson l,m,rt<<1 5 #define rson m+1,r,rt<<1|1 6 const int MAXN=200000+5; 7 const int INF=0x3f3f3f3f; 8 const int MOD=1e9+7; 9 10 int fa[MAXN<<1]; 11 int finds(int x){ 12 if(fa[x]==x) return x; 13 return fa[x]=finds(fa[x]); 14 } 15 int main(){ 16 int r,c,n,m,q; 17 scanf("%d%d%d",&n,&m,&q); 18 for(int i=1;i<=n+m;i++) fa[i]=i; 19 for(int i=0;i<q;i++){ 20 scanf("%d%d",&r,&c); 21 int f1=finds(r),f2=finds(c+n); 22 if(f1!=f2) fa[f1]=f2; 23 } 24 int ans=0; 25 int root=finds(1); 26 for(int i=1;i<=n+m;i++){ 27 int temp=finds(i); 28 if(temp!=root){ 29 ans++; 30 fa[temp]=root; 31 } 32 } 33 printf("%d ",ans); 34 return 0; 35 }
以上是关于CF1013D Chemical table的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces 1021B. Chemical table(并查集)
Microfluidic chemical transistor
CF Codeforces Round #256 (Div. 2) D (448D) Multiplication Table
Deep Protein Methylation Profiling by Combined Chemical and Immunoaffinity Approaches Reveals Novel