백준 4195번, 친구 네트워크 풀이
2020. 10. 14. 21:38ㆍProblem Solving/백준
문제
풀이
Union Find를 구현하여 해당 집합에 몇 개의 원소가 속하는지는 개수를 관리하는 배열을 하나 더 만들어주면 됩니다.
관리해야 할 원소가 string이여서 까다롭기 때문에 이 문제가 Gold II(solved 기준)이지 않을까 생각합니다.
C++에서는 unordered_map이라는 자료구조를 사용하여 $ mp[string] = int $라고 두면, 이론상 $ O(1) $로 각 유저의 string에 대해서 UF의 원소 int를 가져올 수 있습니다. (unordered_map<string, int> mp)
map이 마음에 안든다 싶으면.. set<string> 등으로 이진 탐색을 사용하는 $ O(log N) $짜리 테이블도 만들 수 있을 것 같습니다.
UF에서 개수를 구하는 구현은 코드가 쉽기 때문에 설명은 생략합니다.
소스코드
#include <bits/stdc++.h>
using namespace std;
unordered_map<string, int> mp;
int UF[200000], unc[200000];
int find(int a) {
return UF[a] = a == UF[a] ? a : find(UF[a]);
}
void merge(int a, int b) {
int x = find(a), y = find(b);
if (x == y) return;
UF[x] = y;
unc[y] += unc[x];
unc[x] = 0;
}
void init(int size) {
mp.clear();
//한 줄에 사람이 2명이기 때문에 N*2만큼 초기화
for (int i = 0; i < size * 2; i++) {
UF[i] = i;
unc[i] = 1;
}
}
int getIdFromName(string &name) {
return mp[name] = !mp[name] ? mp.size() : mp[name];
}
int main() {
cin.tie(0)->sync_with_stdio(0);
cout.tie(0);
int T;
cin >> T;
while (T--) {
int f; cin >> f;
init(f);
while (f--) {
string a, b; cin >> a >> b;
int x = getIdFromName(a), y = getIdFromName(b);
merge(x, y);
cout << unc[find(x)] << "\n";
}
}
}
'Problem Solving > 백준' 카테고리의 다른 글
백준 9694번, 무엇을 아느냐가 아니라 누구를 아느냐가 문제다 풀이 (0) | 2020.10.16 |
---|---|
백준 17612번, 한국정보올림피아드 KOI 2019년 1차 대회 고등부 1번, 쇼핑몰 풀이 (0) | 2020.10.15 |
백준 15976번, 한국정보올림피아드 2018년 고등부 2번, XCorr 풀이 (0) | 2020.10.13 |
백준 1226번, BOI 2008 4번, 국회 풀이 (0) | 2020.10.12 |
백준 14867번, 한국정보올림피아드 2017년 고등부 1번, 물통 풀이 (0) | 2020.10.11 |