백준 알고리즘 4195번 : 친구 네트워크

Zoo Da·2021년 9월 4일
0

백준 알고리즘

목록 보기
198/337
post-thumbnail

링크

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

sol1) 유니온 파인드

#include <bits/stdc++.h>
#define X first
#define Y second
#define pb push_back
#define sz(a) int((a).size())
#define fastio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define all(v) v.begin(), v.end()
using namespace std;
using ll = long long;
using ull = unsigned long long;
using dbl = double;
using ldb = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using wector = vector<vector<int>>;
using tii = tuple<int,int,int>;

struct UnionFind {
	vector<int> parent, rank, cnt;
	UnionFind(int n) : parent(n), rank(n, 1), cnt(n, 1) {
		iota(parent.begin(), parent.end(), 0);
	}
	int Find(int x) {
		return x == parent[x] ? x : parent[x] = Find(parent[x]);
	}
	int Union(int a, int b) {
		a = Find(a), b = Find(b);
		if (a == b) return cnt[a];
		if (rank[a] < rank[b]) swap(a, b);
		parent[b] = a;
		rank[a] += rank[a] == rank[b];
		cnt[a] += cnt[b];
		return cnt[a];
	}
};

int main() {
  fastio;
  int tc; cin >> tc;
  while(tc--){
    int n,cnt = 1; cin >> n;
    UnionFind UF(2 * n);
    unordered_map <string, int> UM;
    for(int i = 1; i <= n; i++){
      string a,b; cin >> a >> b;
      if(!UM.count(a)) UM[a] = cnt++;
      if(!UM.count(b)) UM[b] = cnt++;
      cout << UF.Union(UM[a], UM[b]) << "\n";
    }
  }
  return 0;
}

복습(2021-09-08, 136ms)

#include <bits/stdc++.h>
#define X first
#define Y second
#define pb push_back
#define sz(a) int((a).size())
#define fastio ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define all(v) v.begin(), v.end()
using namespace std;
using ll = long long;
using ull = unsigned long long;
using dbl = double;
using ldb = long double;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using wector = vector<vector<int>>;
using tii = tuple<int,int,int>;

struct UnionFind {
	vector<int> parent, rank, cnt;
	UnionFind(int n) : parent(n), rank(n, 1), cnt(n, 1) {
		iota(parent.begin(), parent.end(), 0);
	}
	int Find(int x) {
		return x == parent[x] ? x : parent[x] = Find(parent[x]);
	}
	int Union(int a, int b) {
		a = Find(a), b = Find(b);
		if (a == b) return cnt[a];
		if (rank[a] < rank[b]) swap(a, b);
		parent[b] = a;
		rank[a] += rank[a] == rank[b];
		cnt[a] += cnt[b];
		return cnt[a];
	}
};

int main() {
  fastio;
  int tc; cin >> tc;
  while(tc--){
    unordered_map <string, int> M;
    int n,temp = 1; cin >> n;
    UnionFind UF(2 * n);
    while(n--){
      string a,b; cin >> a >> b;
      if(!M.count(a)) M[a] = temp++;
      if(!M.count(b)) M[b] = temp++;
      cout << UF.Union(M[a], M[b]) << "\n";
    }
  }
  return 0;
}

집합의 크기를 출력해주면 되는 문제입니다.
동명이인이 있을 수도 있기 때문에 unordered_map을 사용하였고, 이미 나왔던 이름의 value값을 새로 할당해주면 안되기 때문에 unordered_map안의 메소드중 key값이 존재하는지 확인하는 메소드인 count를 활용하였습니다.
UnionFind구조체 안에서 Union함수를 bool형이 아닌 집합의 크기를 반환하도록 고쳐주었습니다.

profile
메모장 겸 블로그

0개의 댓글