1. 程式人生 > >圖—並查集(解決朋友圈問題)

圖—並查集(解決朋友圈問題)

      圖也是一種 非線性結構,是由多個頂點組成的關係集合組成的一種資料結構。圖可以分為兩種,無向圖和有向圖。

★圖的定義:

wKioL1eUFjzTw922AABLk_4oE4g613.png

★典型問題:

      利用圖能夠解決很多問題,這裡有一個較為典型的問題,假如已知有n個人和m對好友關係(存於數字r)。如果兩個人是直接或者間接的好友(即就是好友的好友...),則認為他們屬於一個朋友圈,請寫出程式求出這n個人裡一共有多少個朋友圈。

      例如:n = 5, m = 3, r = {{1,2},{2,3},{4,5}}, 表示有5個人,1和2是朋友,2和3也是朋友,4和5是朋友,則1,2,3屬於一個朋友圈,4、5屬於另一個朋友圈,結果為2個朋友圈。

★解題思路:

      首先,先介紹一個概念:並查集。並查集就是將N個不同元素分成一組不想交的集合,開始時,每個元素就是一個集合,然後按規律將兩個集合進行合併。具體的做法如下:    

     設定一個有N個元素的陣列,將每個元素對應的位置都置為-1,即就是先讓其沒有相交,然後根據題目中給出的朋友關係,將根節點元素對應的位置減1,將與根節點是好友的元素對應的位置更改為根節點元素,按照這樣的方式,將所有的關係都進行對應,最後陣列中如果是負數,所對應的元素就是根節點。

wKiom1eUHxySzhg_AAAl9PnIqoE328.png

★具體程式碼:

#pragma once
#include <assert.h>
//實現圖  ——並查集
/*
主要功能:給定一個範圍,能夠確定朋友圈的個數
*/

class UnionFindSet
{
public:
     UnionFindSet(size_t size)    //建構函式
          :_n(size)
          , _set(new int[size])
     {
          for (int i = 0; i < size; i++)     //將_set中的資料最先初始化為-1
          {
               _set[i] = -1;
          }
     }
     
     void Union(int root1, int root2)    //結合兩個根節點
     {
          assert(_set[root1] < 0);
          assert(_set[root2] < 0);
          _set[root1] += _set[root2];
          _set[root2] = root1;
     }
     
     size_t FindRoot(int child)
     {
          if (_set[child] < 0)   //負數證明這個節點就是根節點
          {
               return child;
          }
          int num = _set[child];
          while (num >= 0)
          {
               num = _set[num];
          }
          return num;
     }
     
     void print()
     {
          int root = 0;
          for (int i = 0; i < _n; i++)
          {
               if (_set[i] < 0)
               {
                    root++;
               }
          }
          cout << "輸出有幾個朋友圈:" << root << endl;
     }
     
protected:
     int* _set;    //陣列指標
     size_t _n;     //給定範圍資料的個數
};

void Test()
{
 UnionFindSet ht(10);
 ht.Union(0, 6);
 ht.Union(0, 7);
 ht.Union(0, 8);
 ht.Union(1, 4);
 ht.Union(1, 9);
 ht.Union(2, 3);
 ht.Union(2, 5);
 ht.print();
}

本文出自 “無心的執著” 部落格,謝絕轉載!

相關推薦

解決朋友問題

      圖也是一種 非線性結構,是由多個頂點組成的關係集合組成的一種資料結構。圖可以分為兩種,無向圖和有向圖。★圖的定義:★典型問題:      利用圖能夠解決很多問題,這裡有一個較為典型的問題,假如已知有n個人和m對好友關係(存於數字r)。如果兩個人是直接或者間接的好友

bzoj3706反色刷 尤拉+尤拉性質簡介

題意:一個無向圖,每條邊有黑白兩種顏色,要求用最少的反色刷使得所有邊變為白色,注意刷子會回到出發點。 明顯歐拉回路,注意到歐拉回路的性質,即無向圖任意點的點數不能使奇數。那麼我們用並查集維護每個連通塊

兩個版本

new i++ for void returns parent AR 不知道 stat 1 import java.util.*; 2 3 public class Dis

【模板】洛谷P3367

Description   如題,現在有一個並查集,你需要完成合並和查詢操作。 Input   第一行包含兩個整數\(N\)、\(M\),表示共有\(N\)個元素和\(M\)個操作。   接下來M行,每行包含三個整數\(opt\)、\(a\)、\(b\)   當\(opt=1\)時,將\(a\)與\(b

資料結構學習筆記------附cf例題

並查集是將原始的資料集S看成一個森林,每棵樹代表一個集合。初始時,每個資料看成一顆只有根節點的樹,根據具體要求,將若干樹合併起來組成若干個含有節點較多的樹,每棵樹就是一個集合。此資料結構可以方便的對資料集S進行:(1)查詢其屬於哪個集合(2)將一個集合合併到另一個集合的操作。要注意的是,

Union-Find Set

並查集的三種操作  (1)Union(Root1, Root2):把子集合Root2併入集合Root1中。要求這兩個集合互不相交,否則不執行合併。 (2)Find(x):搜尋單元素x所在的集合,並返回該集合的名字。 (3)UnionFindSets(s):建構函式,將並查

Union-find Sets

1.並查集是什麼 定義:並查集是一種用來管理元素分組情況的資料結構。並查集可以高效的進行以下操作。不過注意並查集雖然可以進行合併操作,但是卻無法進行分割操作; 一.用來查詢元素a和元素b是否屬於同一組。 二.合併元素a和元素b

POJ2492_帶權註釋很詳細

/* 題目大意:有一個教授正在研究一種昆蟲,他認為這種昆蟲之中沒有同性戀。 有n只這種昆蟲,他們之間有k個關係(不知道他們是什麼性別) 這k個關係大概是a與b交往(教授認為只有異性可以交往) 問給的這組資料能否支援教授的觀點 解題思路:可以用帶權並查集來求解

按秩合併

並查集-按秩合併 題目:UVA-11354 題目大意:給出一張n個點m條邊的無向圖, 每條邊有一個危險度,有q個詢問, 每次給出兩個點s、t,找一條路, 使得路徑上的最大危險度最小。 思路:首先,我們可以發現,如果求一個最小生成樹, 那麼任意兩點, 在生成

小米麵試題求朋友的個數

(一)並查集的引入 以小米的這道題為例      並查集定義:並查集實際上是右一個數組實現的,這個陣列比較特殊,最開始將陣列的每一個數據看成一個單獨的集合,用-1表示。然後根據題目要求1和2可以合

連通的判斷, DFS, BFS

 首先要明確什麼是連通圖??? 連通圖:對於一個圖來說,圖中的任意一個點都能訪問到所有的點,則說明該圖連通   很明顯,如果要判斷一個圖是否連通,則必須要從任意一個搜尋一遍,判斷是否到達了所有的點,則很快會想到DFS和BFS。但是用並查集去判斷是否連通

【bzoj4423】[AMPPZ2013]Bytehattan平面圖轉對偶+

  題目傳送門:bzoj4423   如果是普通的刪邊判連通性,我們可以很顯然的想到把操作離線下來,倒著加邊。然而,這題強 制 在 線。   雖然如此,但是題目所給的圖是個平面圖。那麼我們把它轉成對偶圖試試看?   在對偶圖上,刪邊變成了加邊(把邊兩邊的網格連通起來)。並且,我們可以發現,如果在對偶圖上

NOIP模擬 戰爭反向建+

QAQ 【題目分析】 好菜好菜。。。。。fAKe dalao ldx差點就AK了啊。。。。。。。再看看自己的分。。。。。【捂臉】 之前還做過同類型的題啊,藍瘦。 正難則反,既然刪點難以維護,就考慮向圖中加點,直接離線處理。 首先讀入所有操作,統計最後剩下的所有點產生

CodeForces 731C-Socks聯通

C. Socks time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Arseniy is

BZOJ 4551: [Tjoi2016&Heoi2016]樹 &&論?

gis define 並查集 tchar 圖論 name else sig zoj 反向操作,先把所有的標記都打上(記得統計標記的數目),然後依次撤銷,合並到自己的上一個點pre,即fa[u]=getf(pre[u]) #include<cstdio>

[BZOJ 3211]花神遊歷各國+樹狀數組

image fin 不為 names src scrip 樹狀數組 add bsp Description Solution 樹狀數組單點修改區間查詢 我們知道一個數n最多修改loglogn次就會變為1 並查集維護每個數右邊第一個不為1的位置 #inclu

Knight Tournament 偽區間合

rst hat put cif after line spec class std Knight Tournament Hooray! Berl II, the king of Berland is making a knight tournament. The kin

洛谷P3402 【模板】可持久化可持久化線段樹,線段樹

std 樹節點 https case 深度 build eof spa 復雜度 orz TPLY 巨佬,題解講的挺好的。 這裏重點梳理一下思路,做一個小小的補充吧。 寫可持久化線段樹,葉子節點維護每個位置的fa,利用每次只更新一個節點的特性,每次插入\(logN\)個節點,

【bzoj5183】[Baltic2016]Park 離線+對偶+

移動 維護 sca 2個 %d 一行 else if {} clu 題目描述 在Byteland的首都,有一個矩形圍欄圍起來的公園。在這個公園裏樹和訪客都以一個圓形表示。公園有四個出入口,每個角落一個(1=左下角,2=右下角,3=右上角,4=左上角)。訪客能通過這些出入口

POJ-1984-Navigation Nightmare+帶權中級

sof 走了 Go problem name 更新 討論 nio scan 傳送門:Navigation Nightmare 參考:1:https://www.cnblogs.com/huangfeihome/archive/2012/09/07/2675123.html