Disjoint Set,(一个元素不同时属于多个集合)。这里用森林结构代表集合集,树代表集合,根元素为代表元素 用rank数组记录数高。
FIndSet(x) 求包含元素晓得集合的代表元素,
在树中,查找x,后返回代表元素,同时压缩路径,将x,到根的所有节点指向根节点。降低搜索时间。
unite(x,y) 将树x,y合并。
将树高度低的加到树高的集合,使高度低的集合根节点指向高度高的根节点。
#include<iostream>
#include<vector>
using namespace std;
class DisjointSet{ //森林结构
public:
vector<int> rank,p;
DisjointSet() {} //构造方法
DisjointSet(int size) {
rank.resize(size,0);
p.resize(size,0);
for (int i=0;i<size;i++) makeSet(i); //建立树
}
void makeSet(int x) {
p[x]=x;
rank[x]=0;
}
bool same(int x,int y) {
return findSet(x)==findSet(y);
}
void unite(int x,int y) {
link(findSet(x),findSet(y));
}
void link(int x,int y) {
if (rank[x]>rank[y]) { //这里用数组下表表示节点即元素,数组里的数为代表元素
p[y]=x;
}
else {
p[x]=y;
if (rank[x]==rank[y]) {
rank[y]++;
}
}
}
int findSet(int x) {
if (x!=p[x]) { //高度为零时,代表元素即元素
p[x]=findSet(p[x]); //p[x],即为代表元素的下标?
}
return p[x];
}
};
int main() {
int n,a,b,q;
int t;
cin>>n>>q;
DisjointSet ds=DisjointSet(n);
for (int i=0;i<q;i++) {
cin>>t>>a>>b;
if (t==0) ds.unite(a,b);
else if (t==1) {
if (ds.same(a,b)) cout <<1<<endl;
else cout<<0<<endl;
}
}
return 0;
}
#include<vector>
using namespace std;
class DisjointSet{ //森林结构
public:
vector<int> rank,p;
DisjointSet() {} //构造方法
DisjointSet(int size) {
rank.resize(size,0);
p.resize(size,0);
for (int i=0;i<size;i++) makeSet(i); //建立树
}
void makeSet(int x) {
p[x]=x;
rank[x]=0;
}
bool same(int x,int y) {
return findSet(x)==findSet(y);
}
void unite(int x,int y) {
link(findSet(x),findSet(y));
}
void link(int x,int y) {
if (rank[x]>rank[y]) { //这里用数组下表表示节点即元素,数组里的数为代表元素
p[y]=x;
}
else {
p[x]=y;
if (rank[x]==rank[y]) {
rank[y]++;
}
}
}
int findSet(int x) {
if (x!=p[x]) { //高度为零时,代表元素即元素
p[x]=findSet(p[x]); //p[x],即为代表元素的下标?
}
return p[x];
}
};
int main() {
int n,a,b,q;
int t;
cin>>n>>q;
DisjointSet ds=DisjointSet(n);
for (int i=0;i<q;i++) {
cin>>t>>a>>b;
if (t==0) ds.unite(a,b);
else if (t==1) {
if (ds.same(a,b)) cout <<1<<endl;
else cout<<0<<endl;
}
}
return 0;
}