Algorithm

[백준 Gold 2] 4195 친구 네트워크 - Java

Ray 2021. 12. 28. 19:55

문제링크 : https://www.acmicpc.net/problem/4195

 

4195번: 친구 네트워크

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

www.acmicpc.net

 

접근 과정 : 

  • 익숙한 유형이라고 생각했다.
  • 노드의 부모를 알 수 있는 자료구조와, 해당 노드가 부모인 그룹의 수를 저장하는 자료구조를 이용해서 풀이했다.
  • 보통 익숙한 문제에서는 노드를 숫자로 주기때문에, 2개의 배열을 이용해서 쉽게 풀 수 있다.
  • 해당 문제는 String값으로 노드가 주어졌고, 총 몇명의 친구가 주어지는지 확실하지 않았다.
  • 그래서 HashMap으로 노드의 아이디를 저장하고, List를 통해 부모 노드와 그룹의 인원을 파악하려고 했다..
  • 또 다른 방법으로는 친구의 최대 인원을 알 수 있기 때문에, 배열을 최대한으로 생성해놓고 풀이했다.
  • HashMap+List / HashMap+Array 두개의 방법으로 풀이했다.

 

소스 코드 및 결과 :

/* 
    친구 네트워크
    
    HashMap + List
*/

import java.io.*;
import java.util.*;

public class BOJ4195_copy {

    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());

        while (T-- > 0) {
            int F = Integer.parseInt(br.readLine());

            friendsId = new HashMap<>();
            id = 0;
            root = new ArrayList<>();
            group = new HashMap<>();

            while (F-- > 0) {

                st = new StringTokenizer(br.readLine());
                int a = getID(st.nextToken());
                int b = getID(st.nextToken());

                a = findRoot(a);
                b = findRoot(b);

                if (a != b) {
                    root.set(b, a);
                    group.put(a, group.getOrDefault(a, 1) + group.getOrDefault(b, 1));
                }

                sb.append(group.get(a)).append("\n");

            }
        }

        System.out.println(sb.toString());
    }

    static HashMap<String, Integer> friendsId;
    static List<Integer> root;
    static HashMap<Integer, Integer> group;
    static int id;

    static int getID(String a) {
        if (!friendsId.containsKey(a)) {
            friendsId.put(a, id);
            root.add(id);
            id++;
        }

        return friendsId.get(a);

    }

    static int findRoot(int a) {
        if (root.get(a) == a) {
            return a;
        }

        root.set(a, findRoot(root.get(a)));

        return root.get(a);
    }

}

 

 

package BOJ;

/* 
    친구 네트워크
*/

import java.io.*;
import java.util.*;

public class BOJ4195 {

    public static void main(String[] args) throws NumberFormatException, IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        StringBuilder sb = new StringBuilder();

        int T = Integer.parseInt(br.readLine());

        while (T-- > 0) {
            int F = Integer.parseInt(br.readLine());

            HashMap<String, Integer> friendsId = new HashMap<>();
            int id = 1;
            root = new int[F * 2 + 1];
            group = new int[F * 2 + 1];
            Arrays.fill(group, 1);

            while (F-- > 0) {

                st = new StringTokenizer(br.readLine());
                String a = st.nextToken();
                String b = st.nextToken();
                friendsId.putIfAbsent(a, id++);
                friendsId.putIfAbsent(b, id++);

                int aRoot = findRoot(friendsId.get(a));
                int bRoot = findRoot(friendsId.get(b));

                if (aRoot != bRoot) {
                    root[bRoot] = aRoot;
                    group[aRoot] += group[bRoot];

                }

                sb.append(group[aRoot]).append("\n");
            }
        }

        System.out.println(sb.toString());
    }

    static int[] root;
    static int[] group;

    static int findRoot(int a) {
        if (root[a] == 0) {
            return root[a] = a;
        }
        if (root[a] == a) {
            return a;
        }

        return root[a] = findRoot(root[a]);
    }

}

 

P.S 

속도는 배열을 사용한 풀이가 더 빨랐다.