资源限制
时间限制:2.0s 内存限制:256.0MB
问题描述
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
样例说明
其合根情况参考下图
该算法之我的思路
- 我利用并查集的思想及父子节点关联的规律求解该题。
首先确定上图中父子节点关联情况,如2和3关联,就将3的父节点指向2。之后按照此过程依次进行关联。。。
所以以此建立父节点数组,并完成了父节点数组的初始化。
需要注意的是有的节点不止一个父节点,比如8,节点8的父节点首先对应4,之后又对应了7,所以我这样处理:如果节点存在父节点,则让该节点的另一个父节点变为该节点的子节点,相当于将题中根的生长方向转换一下,这样不影响结果。
初始化父节点数组后,只需查找父节点数组中没有父节点的数目即可求得结果。 - 说明下,下面算法依照上面所说思想完成,但是结果在蓝桥官网练习系统上未正确。然而思想正确,希望看到的人也能思考下出错点。若能改正确,请在CSDN中联系我。查看运行正确算法,点此链接:https://blog.csdn.net/zxwsbg/article/details/80374585
算法展示
#include <iostream>
using namespace std;
int main()
{
int m,n;
int k;
int plink[1000000];//父节点
int tempH,tempT;//头部和尾部标识
cin>>m>>n;
cin>>k;
for(int i=0;i<k;i++)
{
cin>>tempH>>tempT;
//判断某节点的父节点是否已经存在,已存在则将当前该节点的另一个父节点作为该节点的子节点存储,不存在则关联父子节点
if(plink[tempT]!=0)plink[tempH]=tempT;
else plink[tempT]=tempH;
}
int count=0;//和根数
//查找和根数
for(int i=1;i<=(m*n);i++)
{
if(plink[i]==0)count++;
}
cout<<count<<endl;
return 0;
}