본문 바로가기

알고리즘

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

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

 

4195번: 친구 네트워크

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

www.acmicpc.net


 


접근 방법

각각의 문자가 들어올 때 map의 기능을 활용하여 , 이미 등록이 되어있는지 확인을 해준다.

이미 들어왔던 문자열이면 그 문자열의 value를 반환해주고, 새로 들어오는 문자열이면 새로운 value를 부여한 후 반환해준다.

이렇게 반환된 value들을 union find를 하여 연결을 시켜주면, 해결이 가능하다.

union find의 과정에서 각각의 자식들의 갯수도 합쳐주는 과정을 해야 한다.


코드

 

#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
map<string,int> m;
map<string, int>::iterator it;
int n;
string s1,s2;
int counter;
int par[100000];
int chi[100000];
int find(int x) { //부모를 find하는 과정,
//이 과정에서 부모를 여러번 거쳐서 가야하면 바로바로 업데이트 해준다.
	if (par[x] == x) {
		return x;
	}
	else {
		return par[x] = find(par[x]); //바로바로 업데이트 하는 과정
	}
}
int unionFun(int x, int y) //유니온 파인드 해주는 함수
{
	x= find(x);
	y = find(y);
	if (x != y) {
		if (x< y) { //부모의 값이 더 작은쪽으로 부모를 맞춰준다.
			par[y] = x;
			chi[x] += chi[y];
			return chi[x];
		}
		else {
			par[x] = y;
			chi[y] += chi[x];
			return chi[y];
		}
	}
	else { //부모가 같다면 연결할 필요가 없이 바로 자식의 갯수를 반환해줌
		return chi[x];
	}	
}
int main() {	
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	int t;
	cin >> t;
	for (int a = 0; a < t; a++) {
		cin >> n;
		for (int i = 0; i < n; i++) {
			cin >> s1 >> s2;
			int k1, k2;
			it = m.find(s1); //s1이라는 문자열이 map에 있는지 확인
			if (it != m.end()) { //맵에 있다면
				k1 = it->second; //맵에 있는 value를 k1에 저장
			}
			else { //맵에 없다면
				k1 = counter; //새로운 value를 생성후 맵에 삽입해준다.
				m.insert({ s1, counter });
				par[counter] = counter; //새로 생성되는 노드의 부모는 자기자신을 가르킴
				chi[counter] = 1; //새로 생성되는 노드의 자식의 갯수(자신 포함)은 한개
				counter++;
			}
			it = m.find(s2); //s1과 같은 과정
			if (it != m.end()) {	
				k2 = it->second;
			}
			else {
				k2 = counter;
				m.insert({ s2, counter });
				par[counter] = counter;
				chi[counter] = 1;
				counter++;
			}
			cout<<unionFun(k1, k2)<<'\n'; //위의 과정에서 반환한 두개의 값을 대입
		}
		m.clear();//테스트 케이스가 바뀔 때 마다 맵을 초기화해줘야함
	}
}

분리집합과 map을 동시에 사용하게 되는, 아이디어는 금방 떠올렸지만 생각보다 구현이 꽤 걸린 문제였다.

'알고리즘' 카테고리의 다른 글

[백준] 1516번 게임개발 [C++]  (0) 2022.05.06
[백준] 2482번 색 상환 [C++]  (0) 2022.05.04
[백준] 1948번 임계경로 [C++]  (0) 2022.05.02
[백준] 1766번 문제집 [C++]  (0) 2022.05.02
[백준] 1005번 ACM Craft [C++]  (0) 2022.05.01