[蓝桥杯 2017 国 C] 合根植物
题目描述
w 星球的一个种植园,被分成 m × n m \times n m×n 个小格子(东西方向 m m m 行,南北方向 n n n 列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式
第一行,两个整数 m m m, n n n,用空格分开,表示格子的行数、列数( 1 < m , n < 1000 1<m,n<1000 1<m,n<1000)。
接下来一行,一个整数 k k k,表示下面还有 k k k 行数据 ( 0 < k < 1 0 5 ) (0<k<10^5) (0<k<105)。
接下来 k k k 行,第行两个整数 a a a, b b b,表示编号为 a a a 的小格子和编号为 b b b 的小格子合根了。
格子的编号一行一行,从上到下,从左到右编号。
比如: 5 × 4 5 \times 4 5×4 的小格子,编号:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
输出格式
一行一个整数,表示答案
样例 #1
样例输入 #1
5 4
16
2 3
1 5
5 9
4 8
7 8
9 10
10 11
11 12
10 14
12 16
14 18
17 18
15 19
19 20
9 13
13 17
样例输出 #1
5
提示
样例解释
时限 1 秒, 256M。蓝桥杯 2017 年第八届国赛
思路: 使用并查集维护所有连根植物,然后遍历所有植物,找出并查集中父节点的个数即可。
代码:
#include<bits/stdc++.h>
using namespace std;
int m, n, k, fa[1000005], ans = 0;
bool vis[1000005];
int getfa(int x){
return fa[x] == x ? x : (fa[x] = getfa(fa[x]));
}
void merge(int x, int y){
fa[getfa(x)] = getfa(y);
}
bool check(int x, int y){
return getfa(x) == getfa(y);
}
int main(){
cin >> m >> n >> k;
for(int i = 1; i <= m * n; i++){
fa[i] = i;
}
for(int i = 0; i < k; i++){
int a, b;
cin >> a >> b;
merge(a, b);
}
for(int i = 1; i <= m * n; i++){
if(!vis[getfa(i)]){
vis[getfa(i)] = true;
ans++;
}
}
cout << ans;
return 0;
}