并查集

并查集

并查集的基本代码

1. 初始化
void init(int n)
{
	for (int i = 1; i <=n; i++)
	{
		fa[i] = i;
	}
}//将所有节点的父节点初始化为自身
2. 查询
int find(int i)
{
	if (fa[i] == i)
		return i;
	else
	{
		fa[i] = find(fa[i]);//合并路径所有节点指向最终父节点
		return find(fa[i]);//寻找父节点
	}
}
3. 合并
void uinounn(int i, int j)
{
	int ifa = find(i);
	int jfa = find(j);
	if (a[ifa] <= a[jfa])
		fa[ifa] = jfa;
	else
		fa[jfa] = ifa;//将相关连的集合合并
}

例题一丶分糖果

在一个幼儿园里面有n个小朋友,分别编号1,2,...,n 。在这些小朋友中有一些小朋友互为朋友关系,总共有m对朋友。
作为幼儿园老师,你想买一些糖果分给小朋友,你知道第i个小朋友想要至少a[i]个糖果,否则他就会不开心。
同时,如果一个小朋友得到的糖果数小于他某个朋友得到的糖果数,他也会不开心。
请问你最少买多少糖果才能保证每个小朋友都不会不开心呢?
第一行以空格分隔的两个整数n,m。
第二行以空格分隔的n个正整数a[i]。
接下来m行每行以空格分隔的两个正整数u,v,代表u是v的朋友,v是u的朋友。
测试用例:
3 1
1 2 3
1 2
输出用例:
7

#include <iostream>
using namespace std;
typedef long long ll;
const ll M = 1000001;
ll a[M];
ll fa[M];
ll b[M];
void init(ll n)
{
	for (ll i = 1; i <=n; i++)
	{
		fa[i] = i;
	}
}
int find(ll i)
{
	if (fa[i] == i)
		return i;
	else
	{
		fa[i] = find(fa[i]);
		return find(fa[i]);
	}
}
void inte(ll i, ll j)
{
	ll ifa = find(i);
	ll jfa = find(j);
	if (a[ifa] <= a[jfa])
		fa[ifa] = jfa;
	else
		fa[jfa] = ifa;
}
int main()
{
	ll n, m;
	cin >> n >> m;
	for (ll i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	for (ll i = 1; i <= 2 * m; i++)
		cin >> b[i];
	init(n);
	for (ll i = 1; i <= 2 * m; i += 2)
	{
		inte(b[i],b[ i + 1]);
	}
	ll sum=0;
	for (ll i = 1; i <= n; i++)
	{
		sum += a[find(i)];
	}
	cout << sum;
}

例题二丶好朋友

有一个叫作“数码世界”的奇异空间,在数码世界里生活着许许多多的数码宝贝,其中有些数码宝贝之间可能是好朋友。并且数码世界有两条不成文的规定:
第一,数码宝贝 A 和数码宝贝 B 是好朋友等价于数码宝贝 B 和数码宝贝 A 是好朋友。
第二,如果数码宝贝 A 和数码宝贝 C 是好朋友,而数码宝贝 B 和数码宝贝 C 也是好朋友,那么 A 和 B 也是好朋友。
现在给出这些数码宝贝中所有好朋友的信息,问:可以把这些数码宝贝分成多少组,满足每组中的任意两只数码宝贝都是好朋友,且任意两组之间的数码宝贝都不是好朋友。

输入:

输入的第一行有两个正整数 n(n<=100) 和 m(m<=100),分别表示数码宝贝的个数和好朋友的组数,其中数码宝贝编号为1~n。
接下来有m行,每行两个正整数a和b,表示数码宝贝a和数码宝贝b是好朋友。

输入样例:

4 2
1 4
2 3

输出样例:

2

#include <iostream>
using namespace std;
typedef long long ll;
const ll M = 1000001;
ll fa[M];
ll b[M];
void init(ll n)
{
	for (ll i = 1; i <=n; i++)
	{
		fa[i] = i;
	}
}
int find(ll i)
{
	if (fa[i] == i)
		return i;
	else
	{
		fa[i] = find(fa[i]);
		return find(fa[i]);
	}
}
void inte(ll i, ll j)
{
	ll ifa = find(i);
	ll jfa = find(j);
		fa[ifa] = jfa;
}
int main()
{
	ll n, m;
	cin >> n >> m;
	for (ll i = 1; i <= 2 * m; i++)
		cin >> b[i];
	init(n);
	for (ll i = 1; i <= 2 * m; i += 2)
	{
		inte(b[i],b[ i + 1]);
	}
	ll sum=0;
	for (ll i = 1; i <= n; i++)
	{
		if (fa[i] == i)
			sum++;
	}
	cout << sum;
}
posted @ 2025-07-07 15:39  星空丶star  阅读(3)  评论(0)    收藏  举报