코딩 테스트(Coding Test)/백준
[백준] 4195번 : 친구 네트워크 - 자바(Java)
다문다뭉
2024. 12. 16. 15:56
Problem 🔒
문제
https://www.acmicpc.net/problem/4195
민혁이는 소셜 네트워크 사이트에서 친구를 만드는 것을 좋아하는 친구이다. 우표를 모으는 취미가 있듯이, 민혁이는 소셜 네트워크 사이트에서 친구를 모으는 것이 취미이다.
어떤 사이트의 친구 관계가 생긴 순서대로 주어졌을 때, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오.
친구 네트워크란 친구 관계만으로 이동할 수 있는 사이를 말한다.
입력
첫째 줄에 테스트 케이스의 개수가 주어진다. 각 테스트 케이스의 첫째 줄에는 친구 관계의 수 F가 주어지며, 이 값은 100,000을 넘지 않는다. 다음 F개의 줄에는 친구 관계가 생긴 순서대로 주어진다. 친구 관계는 두 사용자의 아이디로 이루어져 있으며, 알파벳 대문자 또는 소문자로만 이루어진 길이 20 이하의 문자열이다.
출력
친구 관계가 생길 때마다, 두 사람의 친구 네트워크에 몇 명이 있는지 구하는 프로그램을 작성하시오.
더보기
예제 입력 1
2
3
Fred Barney
Barney Betty
Betty Wilma
3
Fred Barney
Betty Wilma
Barney Betty
예제 출력 1
2
3
4
2
2
4
Approach ⭕
- 문자열(친구 이름) 처리
- 유니온 파인드 알고리즘은 숫자 인덱스를 기반으로 동작한다.
- 문자열을 정수 인덱스로 매핑하기 위해서 해시맵을 사용한다.
- 해시맵의 삽입과 조회의 시간 복잡도는 O(1)이다.
- 네트워크 내의 친구 수 출력
- 루트 노드에 집합의 크기(네트워크 내의 친구 수)를 저장하고 반환한다.
- 두 집합을 합칠 때, 각 집합의 크기를 합하여 저장한다.
- 각 집합의 크기가 음수로 저장되며, 절대값이 집합의 크기를 의미한다.
Solution 💡
public class Main {
static int F, tree[], idx;
static HashMap<String, Integer> map = new HashMap<>();
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
while(T-->0){
F = sc.nextInt();
tree = new int[F*2];
Arrays.fill(tree, -1);
map.clear(); // 테케마다 해시맵 초기화
idx = 0; // 이름과 매핑할 인덱스
for(int i=0; i<F; i++){
String f1 = sc.next();
String f2 = sc.next();
// 친구 이름 인덱스 매핑
if(!map.containsKey(f1)) map.put(f1, idx++);
if(!map.containsKey(f2)) map.put(f2, idx++);
// 집합의 크기를 sb에 저장
sb.append(union(map.get(f1), map.get(f2)) + "\\n");
}
}//T
System.out.println(sb);
}
public static int find(int x){
if(tree[x]<=-1) return x;
return tree[x] = find(tree[x]); // 경로 압축
}
public static int union(int a, int b){
a = find(a);
b = find(b);
if(a!=b){ // 두 집합이 서로 다를 때만 수행
tree[a] += tree[b]; // 집합 크기 증가
tree[b] = a; // 자식으로 설정
}
return -tree[a];
}
}