[蓝桥杯 2017 国 C] 合根植物
题目描述
w 星球的一个种植园,被分成 m×nm \times nm×n 个小格子(东西方向 mmm 行,南北方向 nnn 列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入格式
第一行,两个整数 mmm,nnn,用空格分开,表示格子的行数、列数(1<m,n<10001<m,n<10001<m,n<1000)。
接下来一行,一个整数 kkk,表示下面还有 kkk 行数据 (0<k<105)(0<k<10^5)(0<k<105)。
接下来 kkk 行,第行两个整数 aaa,bbb,表示编号为 aaa 的小格子和编号为 bbb 的小格子合根了。
格子的编号一行一行,从上到下,从左到右编号。
比如:5×45 \times 45×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;
}


被折叠的 条评论
为什么被折叠?



