这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
接下来一行,一个整数k,表示下面还有k行数据(0<k<100000)
接下来k行,第行两个整数a,b,表示编号为a的小格子和编号为b的小格子合根了。
格子的编号一行一行,从上到下,从左到右编号。
比如:5 * 4 的小格子,编号:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
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
思路;一道简单的并查集求连通分量的题,比较坑的是n, m都取值范围都是1-1000,所以pre数组要开1e6,当时一看题直接把数组开成1000的了,结果三发交上去都t(搞不清楚),还以为哪里要优化,后来才发现数组开小了,悲剧。。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 50;
int n, m, k, cnt, ans;
int pre[maxn];
void init()
{
ans = 0;
for(int i = 1;i <= cnt;i++)
{
pre[i] = i;
}
return;
}
int Find(int x)
{
int r = x;
while(r != pre[r])
{
r = pre[r];
}
int i = x, j;
while(i != r)//路径压缩
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void join(int a, int b)
{
int fa = Find(a);
int fb = Find(b);
if(fa != fb)
{
pre[fa] = fb;
}
}
int main()
{
while(cin >> n >> m)
{
int u, v;
cnt = n * m;
scanf("%d", &k);
init();
for(int i = 1;i <= k;i++)
{
scanf("%d%d", &u, &v);
join(u, v);
}
for(int i = 1;i <= cnt;i++)
{
if(pre[i] == i) ans++;//根节点的数量就是连通分量的个数
}
printf("%d\n", ans);
}
return 0;
}