并查集是高效的查询两个元素是否属于一个集合的方法,为了使用方便把关系并查集和并查集利用面向对象和泛型编程的思想写在了一起。
template <typename Type>
class DisjointSet {
struct node {
int parent_;
Type relation_; //parent -> this
};
vector<node> nodes;
vector<int> parents;
public:
bool is_relation_;
DisjointSet(int number_nodes, bool is_relation = false) {
is_relation_ = is_relation;
if(is_relation_) {
nodes.resize(number_nodes+1);
for(int i = 0; i <= number_nodes; ++i) {
nodes[i].parent_ = i;
nodes[i].relation_ = 0;
}
} else {
parents.resize(number_nodes+1);
for(int i = 0; i <= number_nodes; ++i)
parents[i] = i;
}
}
int find(int x) {
if(is_relation_) {
if(nodes[x].parent_ != x) {
int xparent = nodes[x].parent_; // x's old parent
nodes[x].parent_ = find(nodes[x].parent_);
nodes[x].relation_ = nodes[x].relation_ + nodes[xparent].relation_;
}
return nodes[x].parent_;
} else {
if(parents[x] != x)
parents[x] = find(parents[x]);
return parents[x];
}
}
Type get_relation(int x) {
return nodes[x].relation_;
}
void merge(int x, int y) {
parents[find(y)] = find(x);
}
void merge(int x, int y, Type relation) {
// relation: x->y
int yparent = find(y);
nodes[yparent].parent_ = find(x);
nodes[yparent].relation_ = nodes[x].relation_ + relation - nodes[y].relation_;
}
};