1. 程式人生 > >小米麵試題--朋友圈問題

小米麵試題--朋友圈問題

假如已知有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和2是好友 讓下標1的位置加-1,然後依次把朋友之間的關係存入這個數組裡邊。

這裡寫圖片描述

#pragma once

class UnionFindSet
{
public:
    UnionFindSet(size_t size)
    {
        _ufs.resize(size, -1);
    }
    int Findroot(int x)
    {
        int root = x;
        while (_ufs[root] >= 0)
        {
            root = _ufs[root];
        }
        return root;
    }
    void Union(int
x1, int x2) { int root1 = Findroot(x1); int root2 = Findroot(x2); if (root1 != root2) { _ufs[root1] += _ufs[root2]; _ufs[root2] = root1; } } bool IsInOneSet(int x1, int x2) { return Findroot(x1) == Findroot(x2); } size_t GetSetSize() { int
count = 0; for (size_t i = 0; i < _ufs.size(); i++) { if (_ufs[i] < 0) count++; } return count; } private: vector<int> _ufs; }; int friends(int n, int m, int r[][2]) { UnionFindSet ufs(n + 1); for (size_t i = 0; i < m; i++) { ufs.Union(r[i][0], r[i][1]); } return ufs.GetSetSize() - 1; //0沒資料 } void TestUnionFindSet() { int n = 5; const int m = 3; int r[m][2] = { { 1, 2 }, { 2, 3 }, { 4, 5 } }; cout << "朋友圈有幾個?" << friends(n, m, r) << endl; }