查并集
查并集主要思想:将不同的集合归于一个集合后,成为一个大的集合,然后去看看所要查的集合是否在这个大的集合里边
下边开始讲实现过程
并:
有四个集合【黑、红、白、蓝】
黑和红,白和蓝,使得黑红两个集合成为以黑集合为头的一个大集合,同理,蓝白以白集合为头的一个大集合
再并黑白两个大集合,就可以看到是以黑集合为头的一个大集合
查:
思路一:通过查询大集合里边是否有对应要查的集合即可 --> 我们可以看到如果访问的是蓝色集合,那么我们从黑色这个大集合下去访问要访问四次(次数还可以接受),但是如果并的集合很多,或者大集合有很多,那么我们的访问时间很容超过1s,很容易被t,这时候要用到思路二的压缩路径。
思路二:压缩路径 --> 即将大集合里的所有集合的上一级都设为对应的头集合,检查对应要查的集合的头集合是否是相同的头集合即可知道是否在同一大集合里。
CODE(模板题)
(https://www.luogu.com.cn/problem/P3367)
#include <bits/stdc++.h>
#define ll long long
#define endl '\n'
using namespace std;
vector<int> ve(100005);
int see(int x){
//实现路径压缩
if(ve[x] == x)return x;
ve[x] = see(ve[x]);
return ve[x];
}
int main() {
int n,m; cin >> n >> m;
for (int i = 1; i <= n; i++) ve[i] = i; //设置n个大集合并标号
for (int i = 1; i <= m; i++) {
int z,x,y;cin >> z >> x >> y;
if(z == 1){ //实现并集
ve[see(x)] = see(y);
}else{ //检查每个集合的头集合是否相同
if(see(x) == see(y))cout << 'Y' << endl;
else cout << 'N' << endl;
}
}
return 0;
}