簡體   English   中英

找出不相交集的數量

[英]Find the number of disjoint sets

對於那些不熟悉Disjoint-set數據結構的人。

https://en.wikipedia.org/wiki/Disjoint-set_data_structure

我想找到不。 來自給定朋友和他們的關系的朋友群體。 當然,毫無疑問,使用BFS / DFS可以很容易地實現這一點。 但是我選擇使用不相交的集合,我也傾向於找到這個人所屬的朋友組等,並且不相交集合肯定聽起來適合那種情況。

我已經實現了Disjoint集數據結構,現在我需要找到它包含的不相交集的數量(這將給出組的數量)。

現在,我堅持實現如何有效地找到不相交集的數量,因為朋友的數量可以大到1 00 00 0。

我認為應該有效的選項。

  1. 將新裝置附在原件背面,然后銷毀舊裝置。

  2. 在每個聯盟中更改每個元素的父母。

但由於朋友數量巨大,我不確定這是否是正確的方法,也許是否有其他有效的方式,或者我應該繼續實施上述任何一種方法。

這是我的代碼以獲取更多細節。(我在這里沒有實現計數不相交集)

//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;
}

在Disjoint Set Data Structure中的兩個項目a,b上的每個聯合操作都有兩種可能的情形:

  1. 您試圖將同一組中的項目聯合起來。 在這種情況下,什么也沒做,並且不相交集的數量保持不變。
  2. 你將來自兩個不同集的項聯合起來,所以你基本上將兩個集合合為一個 - 有效地減少了不相交集的數量。

由此,我們可以得出結論,通過從上面跟蹤類型(2)的聯合數量,很容易在每個時刻找到不相交集的數量。
如果我們用succ_unions表示這個數字,那么每個點的集合總數是number_of_initial_sets - succ_unions

如果您需要知道的是不相交集的數量而不是它們是什么,一個選項是將計數器變量添加到您的數據結構中,計算有多少不相交集。 最初,有n個,每個元素一個。 每次執行並集操作時,如果兩個元素沒有相同的代表,那么您知道將兩個不相交的集合合並為一個,因此可以減少計數器。 這看起來像這樣:

if (pu != pv){ //if not in the same set.
    numDisjointSets--;  // <--- Add thie line
    mst.push_back(graph[i]);
    total += graph[i].first;
    parent[pu] = parent[pv]; // create the link between these two sets
}

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM