Problem Solving/BOJ

[백준 / BOJ] C++ 4195 친구 네트워크

nageune 2023. 4. 6. 11:57
728x90
반응형

4195번: 친구 네트워크

 

문제

https://www.acmicpc.net/problem/4195

 

4195번: 친구 네트워크

첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진

www.acmicpc.net

 

 

풀이

친구 네트워크가 연결될 때마다 네트워크에 연결된 사람의 수를 출력하는 문제다. 각 이름에 대해 번호를 부여하기 위해 map 자료 구조를 사용한다. 만약 map에 이름이 없다면 맵의 사이즈를 번호로 사용하게 한다. 이러면 번호가 0번부터 붙게 된다. 또 N번의 연결이 이루어지는데 각 연결마다 두 명의 이름이 주어지므로 최대 2 × N명의 관계를 받을 수 있다.

 

먼저 각 원소는 스스로 크기가 1인 집합이므로 크기를 나타내는 배열 s를 모두 1로 초기화한다. 그리고 입력받은 두 사람을 union 한다.(네트워크로 연결한다.) 단, 항상 부모 노드는 번호가 작은 쪽을 가리키고 집합을 합칠 때도 번호가 작은 쪽으로 합친다. 만약 두 사람이 이미 같은 네트워크에 포함되어 있다면 집합의 크기를 합치면 안 된다.

 

 

코드

#include <bits/stdc++.h>
using namespace std;

vector<int> p, s;

int find(int x) {
  if (p[x] != x)
    p[x] = find(p[x]);
  return p[x];
}

void merge(int x, int y) {
  x = find(x); // 루트 탐색
  y = find(y); // 루트 탐색
  if (x == y) // 만약 같은 집합이면
    return; // 연결하지 않는다
  // 항상 크기가 작은 쪽으로 연결
  if (x > y)
    swap(x, y);
  // 집합의 크기 더하기
  s[x] += s[y];
  // 두 집합 연결
  p[y] = x;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  int t;
  cin >> t;
  while (t--) {
    int n;
    cin >> n;
    p.resize(2 * n); // 2×N 크기로 재할당
    iota(p.begin(), p.end(), 0); // 0부터 N-1로 할당
    s.resize(2 * n); // 2×N 크기로 재할당
    fill(s.begin(), s.end(), 1); // 모두 1로 초기화
    map<string, int> M;
    while (n--) {
      string a, b; // 두 사람 이름 입력
      cin >> a >> b;
      if (M.find(a) == M.end()) // 아직 번호가 없다면
        M[a] = M.size(); // 번호 할당
      if (M.find(b) == M.end())
        M[b] = M.size();
      // 두 사람을 연결
      merge(M[a], M[b]);
      // 연결된 사람의 집합의 크기(사이즈 배열의 루트 인덱스) 출력
      cout << s[find(M[a])] << '\n';
    }
  }
  return 0;
}

 

728x90
반응형

'Problem Solving > BOJ' 카테고리의 다른 글

[백준 / BOJ] C++ 10775 공항  (4) 2023.04.06
[백준 / BOJ] C++ 1005 ACM Craft  (2) 2023.04.06
[백준 / BOJ] C++ 1766 문제집  (2) 2023.04.05
[백준 / BOJ] C++ 1516 게임 개발  (6) 2023.04.05
[백준 / BOJ] C++ 2252 줄 세우기  (4) 2023.04.04