#include <bits/stdc++.h>
using namespace std;
int uset[1123];
void MakeSet(int n); /// 初始化并查集
int FindBoss(int x); /// 找爹 23333
void Merge(int a, int b); /// 合并
int main()
{
int n,m;
while(cin >> n >> m)
{
int a,b;
MakeSet(n); /// 初始化并查集
while(m--)
{
cin >> a >> b;
Merge(a,b);
}
int cnt = 0;
for(int i = 1; i <= n; i++)
{
if(uset[i] == i)
{
cnt++; /// 如果BOSS是自己 所以为树根
}
}
cout << cnt << endl;
}
return 0;
}
void MakeSet(int n) /// 初始化并查集
{
for(int i = 1; i <= n; i++) /// 注意初始化要从1 开始
{
uset[i] = i; /// 初始将自身的Boss设置为自己
}
}
int FindBoss(int x) /// 找爹 23333
{
if(uset[x] == x)
{
return x; /// 如果此时BOSS为本身 表4此时这就是根节点惹QvQ
}
else
{
/// 楼上为何突然卖萌...
int p = x;
int t;
/// 路径压缩:每次查找时,令查找路径上的每个节点都指向根节点
while(uset[p] != p)
{
p = uset[p]; /// get BOSS!
}
while(x != p)
{
t = uset[x];
uset[x] = p;
x = t;
}
}
return x;
}
void Merge(int a, int b) /// 合并
{
int x = FindBoss(a);
int y = FindBoss(b);
if(x != y) /// 如果他们的BOSS是不同的
{
uset[y] = x;
}
}
树结构练习——判断给定森林中有多少棵树
最新推荐文章于 2024-04-23 17:53:32 发布