并查集

我与影子孤独终老i 提交于 2020-03-11 02:25:00
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f3f3f3f3f
#define mod 1000000007
#define IOS ios::sync_with_stdio(false)
#define endl '\n'
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int f[maxn];
int n, ans;
void init() {//数组初始化(每个人是自己的组先)
	for (int i = 1;i <= n;++i) {
		f[i] = i;
	}
	return;
}
int Get_Father(int v) {
	if (f[v] == v)//如果祖先是自己
		return v;
	else {
		f[v] = Get_Father(f[v]);//否则继续寻找并把途径的所有祖先的祖先设置为最年长的祖先()
		return f[v];//类似于把自己和父亲和爷爷都设置为曾祖父的儿子
	}
}
void Search() {//查找有几个祖先
	for (int i = 1;i <= n;++i) {
		if (f[i] == i)++ans;
	}
	return;
}
void Union_(int a,int b) {
	int t1, t2;
	t1 = Get_Father(a);//寻找a的祖先
	t2 = Get_Father(b);//寻找b的祖先
	if (t1 != t2) {//判断两个结点是否在同一个集合中,即是否为同一个祖先
		f[t2] = t1;//靠左原则 t1为t2的祖先
		//经过路径压缩之后f[b]的根的值也赋值为a的祖先f[t1]
	}
}
int main() {
	IOS;
	cin >> n;
	int t;cin >> t;//多少对信息
	init();
	while (t--) {
		int a, b;cin >> a >> b;
		Union_(a, b);//合并a,b
	}
	Search();//查找有多少个独立的子树
	cout << ans;
}

输入(a,b表示a和b有共同祖先)

10 9
1 2
3 4
5 2
4 6
2 6
8 7
9 7
1 6
2 4

输出

3

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!