并查集
并查集
并查集的基本代码
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;
}

浙公网安备 33010602011771号