算法笔记__并查集

先给出源代码和输入输出测试结果:

#include<iostream>
using namespace std;
const int N = 110;
int father[N];//存放父亲节点
bool isBoot[N];//标记时否为根节点
int findFather(int x)
{
	int a = x;
	while (x != father[x])
		x = father[x];
	while (a != father[a])
	{
		int z = a;
		a = father[a];
		father[z] = x;
	}
	return x;
}

void Union(int a, int b)
{
	int A = findFather(a);
	int B = findFather(b);
	if (A != B)
		father[A] = B;
}

void init(int n)
{
	for (int i = 1; i <= n; i++)
	{
		father[i] = i;
		isBoot[i] = false;
	}
}

int main(void)
{
	int n, m, a, b;
	cin >> n >> m;//n为元素总个数,m为两两为一组的组数
	init(n);//记得初始化
	for (int i = 0; i < m; i++)
	{
		cin >> a >> b;//录入元素关系
		Union(a, b);//合并ab所在集合
	}
	for (int i = 1; i <= n; i++)
	{
		isBoot[findFather(i)] = true;
	}
	int ans = 0;
	for (int i = 1; i <= n; i++)
		ans += isBoot[i];
	cout << "输出根节点:";
	for (int i = 1; i <= n; i++)
		if (i == father[i])
			cout << i<<' ';
	cout << endl;
	cout << "组数:"<<ans<<endl;
	system("pause");
	return 0;
}

路径压缩:就是把当前查询节点的路径上所有的节点的父亲都指向根节点,复杂度可以降为O(1)

非递归:

int findFather(int x)
{
	int a = x;
	while (x != father[x])
		x = father[x];
	while (a != father[a])
	{
		int z = a;
		a = father[a];
		father[z] = x;
	}
	return x;
}

递归:

int findFather(int v)
{
	if (v == father[v])
		return v;
	else
	{
		int F = findFather(father[v]);
		father[v] = F;
		return F;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41938259/article/details/86604306
今日推荐