题目描述
w星球的一个种植园,被分成 m * n 个小格子(东西方向m行,南北方向n列)。每个格子里种了一株合根植物。
这种植物有个特点,它的根可能会沿着南北或东西方向伸展,从而与另一个格子的植物合成为一体。
如果我们告诉你哪些小格子间出现了连根现象,你能说出这个园中一共有多少株合根植物吗?
输入
第一行,两个整数m,n,用空格分开,表示格子的行数、列数(1<m,n<1000)。
接下来一行,一个整数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
输出
多少株
样例输入
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
样例输出
5
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<cmath>
const int maxn=1e6+5;
typedef long long ll;
using namespace std;
int pre[maxn];
int find(int x)
{
if(x==pre[x])//如果这个数是自己的根节点
{
return x;
}
else//找他的根节点
{
return pre[x]=find(pre[x]);
}
}
void Merge(int x,int y)
{
int fx=find(x);//找根节点
int fy=find(y);//找根节点
if(fx!=fy)//如果不一样(两个根节点)
{
pre[fx]=fy;//直接合并
}
return;
}
int main()
{
int n,m;
cin>>n>>m;
int k;
cin>>k;
for(int t=1;t<=n*m;t++)
{
pre[t]=t;
}
int x,y;
for(int t=0;t<k;t++)
{
scanf("%d%d",&x,&y);
Merge(x,y);//合并根节点
}
int ans=0;
for(int t=1;t<=n*m;t++)
{
if(find(t)==t)
{
ans++;
}
}
printf("%d",ans);
return 0;
}