蓝桥杯之合根植物-并查集及父子节点规律求解简化(c++实现)

上文链接:蓝桥杯之未名湖边的烦恼-递归极简版(c++实现)


资源限制

时间限制: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;
}

下文链接:蓝桥杯之小型计算器-分治法思想+简单逻辑判断(c++实现)

发布了30 篇原创文章 · 获赞 3 · 访问量 2761

猜你喜欢

转载自blog.csdn.net/weixin_44077556/article/details/104276073
今日推荐