nit*_*918 4 c++ algorithm disjoint-union disjoint-sets data-structures
对于那些不熟悉脱节集数据结构的人。
https://zh.wikipedia.org/wiki/不相交-set_data_structure
我试图找到不。给定的一组好友及其关系中的一组好友。当然,毫无疑问,这可以使用BFS / DFS轻松实现。但是我选择使用不相交集,我也倾向于找到该人所属的朋友组,等等,并且不相交集听起来确实适合这种情况。
我已经实现了不相交集数据结构,现在我需要找到它包含的不相交集的数量(这将为我提供组数)。
现在,我坚持执行有效地查找不交集的数量的方法,因为朋友的数量可以高达1 00 00 0。
我认为应该起作用的选项。
将新套装装在原件的背面,然后销毁旧套装。
更改每个工会的每个元素的父母。
但是由于朋友数量巨大,所以我不确定这是否是正确的方法,也许还有其他有效的方法,或者我应该继续执行以上任何一种方法。
这是我的代码以获取其他详细信息。(我尚未在此处实现计数不交集)
//disjoint set concept
//https://www.topcoder.com/community/data-science/data-science-tutorials/disjoint-set-data-structures/
// initially all the vertices are takes as single set and they are their own representative.
// next we see, compare two vertices, if they have same parent(representative of the set), we leave it.
// if they don't we merge them it one set.
// finally we get different disjoint sets.
#includes ...
using namespace std;
#define edge pair<int, int>
const int max 1000000;
vector<pair<int, edge > > graph, mst;
int N, M;
int parent[max];
int findset(int x, int* parent){
//find the set representative.
if(x != parent[x]){
parent[x] = findset(parent[x], parent);
}
return parent[x];
}
void disjoints(){
for(int i=0; i<M; i++){
int pu = findset(graph[i].second.first, parent);
int pv = findset(graph[i].second.second, parent);
if(pu != pv){ //if not in the same set.
mst.push_back(graph[i]);
total += graph[i].first;
parent[pu] = parent[pv]; // create the link between these two sets
}
}
}
void noOfDisjoints(){
//returns the No. of disjoint set.
}
void reset(){
for(int i=0; i<N; i++){
parent[i] = i;
}
}
int main() {
cin>>N>>M; // No. of friends and M edges
int u,v,w; // u= source, v= destination, w= weight(of no use here).
reset();
for(int i =0; i<M ;i++){
cin>>u>>v>>w;
graph.push_back(pair<int, edge>(w,edge(u,v)));
}
disjoints();
print();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不a,b交集数据结构中两个项目上的每个联合操作都有两种可能的情况:
由此,我们可以得出结论,通过跟踪上述类型(2)的并集数,很容易在每时每刻找到不相交集的数。
如果用x表示该数字succ_unions,则每个点的总集合数为number_of_initial_sets - succ_unions。
如果您只需要知道不相交集的数量而不是它们是什么,那么一种选择是将计数器变量添加到您的数据结构中,计算有多少不相交集。最初,有n个,每个元素一个。每次执行联合操作时,如果两个元素没有相同的代表,那么您就知道您正在将两个不相交的集合合并为一个,因此您可以递减计数器。这看起来像这样:
if (pu != pv){ //if not in the same set.
numDisjointSets--; // <--- Add this line
mst.push_back(graph[i]);
total += graph[i].first;
parent[pu] = parent[pv]; // create the link between these two sets
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!