有 N 個人,編號 0~N-1,0 號染上了嚴重的傳染性疾病,有與 0 直接或間接接觸的人都需要隔離。請問有多少人需要隔離?
範例測資
範例輸入 | 範例輸出 |
---|---|
第一行有兩個數字 N 和 M,接下來有 M 行,每一行有 2 個數字 A 和 B,代表 A 和 B 有接觸過。 | 輸出有多少人需要隔離。 |
5 3 1 0 0 3 2 4 | 3 |
解題思路
使用 Map 來紀錄每一個人的最底層接觸者,一開始將所有人的 Map 值都預設為 -1。
宣告一個函式 findEnd,需要一個參數 N,如果 N == -1 || Map[N] == -1,return N。如果 Map[N] == N,return N。否則 return findEnd(Map[N])。
輸入資料時,如果兩個人都沒有接觸史,則要判斷其中是否有 0,如果有的話就要將另一個人的 Map 值設定為 0。如果兩個人都有接觸史,則要判斷其中有沒有 0,如果有 0 的話就將另一個人的 Map[findEnd(另一個人)] 設為 0,否則就將其設為 findEnd(另一個人)。如果是一個有一個沒有,則將沒有的人的 Map 值設定成 findEnd(另一個人)。
最後跑一個從 0 到 N-1 的迴圈,如果 findEnd(Map[目前數字]) == 0,就將答案 +1。
範例程式碼-ZeroJudge F677: 並查集練習
#include <iostream>
#include <map>
using namespace std;
map<int, int>MAP;
void virus(const int a, const int b) {
if (MAP[a] == -1 && MAP[b] == -1) {
if (b == 0) {
MAP[a] = b;
MAP[b] = b;
}
else {
MAP[a] = a;
MAP[b] = a;
}
}
else if (MAP[a] != -1 && MAP[b] != -1) {
if (findEnd(MAP[b]) == 0) MAP[findEnd(a)] = 0;
else MAP[findEnd(b)] = findEnd(a);
}
else {
if (MAP[a] != -1) MAP[b] = findEnd(a);
else MAP[a] = findEnd(b);
}
}
int main() {
cin.sync_with_stdio(0);
cin.tie(0);
int N, M, ans = 0;
cin >> N >> M;
for (int i = 1; i<N; i++) MAP[i] = -1;
for (int i = 0; i<M; i++) {
int a, b;
cin >> a >> b;
virus(a, b);
}
for (int i = 0; i<N; i++) {
if (findEnd(MAP[i]) == 0) {
ans++;
}
}
cout << ans << "\n";
}
//ZeroJudge F677
//Dr. SeanXD