[백준 - JAVA] 2606번 : 바이러스

2023. 1. 20. 15:02·Algorithm/Algorithm Problem
  • https://www.acmicpc.net/problem/2606
 

2606번: 바이러스

첫째 줄에는 컴퓨터의 수가 주어진다. 컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 둘째 줄에는 네트워크 상에서 직접 연결되어 있는 컴퓨터 쌍의 수가 주어

www.acmicpc.net

 

문제 조건 파악 및 접근

 

컴퓨터의 수는 100 이하이고 각 컴퓨터에는 1번 부터 차례대로 번호가 매겨진다. 

컴퓨터는 100 이하는 갖지만 최대 간선 수는(n*(n-1)) / 2 이므로 4,950개까지 가능. 

 

그래프 문제고 DFS, BFS을 활용하면 된다.

 

결국 1에 연결된 노드의 개수를 파악하라는게 문제의 최종적인 질문.

 

풀이 1. BFS

 

풀이 2. union-find를 활용

union으로 "동일 집합"을 구성하고 마지막에 1에 연결된 노드 개수만 세주면 되겠다는 생각을 갖게됨.

 

 

 

 

소스 코드


 

Union-Find

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import java.io.*;
import java.util.*;
 
public class _2606_바이러스 {
 
    static int[] computers;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = null;
 
        int N = Integer.parseInt(br.readLine()); // 컴퓨터 개수
        computers = new int[N + 1];
 
        for (int i = 1; i < N + 1; i++) {
            computers[i] = i;
        }
 
        int answer = -1;
 
        int linkCnt = Integer.parseInt(br.readLine());
        for (int i = 0; i < linkCnt; i++) {
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
 
            union(from, to);
 
        }
 
 
        for (int i = 1; i < N + 1; i++) {
            System.out.println(i + " -> " + find(i));
            if(find(i) == 1){
                answer++;
            }
        }
 
        System.out.println(answer);
 
        bw.flush();
        br.close();
        bw.close();
    }
 
    public static void union(int x, int y) {
        x = find(x);
        y = find(y);
 
        if (x == y) {
            return;
        }
 
        if (x < y) {
            computers[y] = x;
        } else {
            computers[x] = y;
        }
    }
 
    public static int find(int x) {
        if (computers[x] == x) {
            return x;
        }
 
        return computers[x] = find(computers[x]);
    }
 
}
 
Colored by Color Scripter
cs

 

 

 

 

Union-Find 복습 및 피드백


 

Union-Find는 다음을 수행한다.

 

  • Union(a, b)를 수행하면 a가 속한 집합과 b가 속한 집합을 합친다.
  • Find(a)는 a가 속한 집합의 '대표'를 반환한다. 즉, Find(a) == Find(b)라는 것은 두 집합의 대표가 동일하다는 의미이므로, a와 b가 동일한 집합에 속해있다는 것과 동치다.

 

 

 

1) 문제에서 주어진 네트워크는 트리가 아니다.

그러니 "5번 노드처럼 저렇게 한개의 노드가 부모를 두개를 갖는 경우에도" 같은 표현은 올바르지 않다. 5번 노드는 1번, 2번 노드와 연결되었을 뿐, 부모를 가지지 않는다.

 

2) Union-Find는 독립적인 트리의 집합을 만드는 것이다. 이 트리 상에서 5번 노드의 부모는 parent[5]에 해당하므로 당연히 하나다.

 

3) Union-Find로 구현된 위 코드의 목적, 즉 '집합을 합치는 것'과 '동일 집합에 속해있는지 판별하는 것'을 잘 수행한다는 것을 믿으면, parent[5]가 1인지, 2인지, 아니면 아예 다른 값인지는 중요하지 않다. 중요한 건 5번 노드와 1번 노드가 동일한 연결 요소에 속했으므로 Find(5) == Find(1)일 것이라는 사실이다.

 

 

 

 

BFS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.io.*;
import java.util.*;
 
 
public class _2606_바이러스_graph {
 
    static int[][] graph;
    static boolean[] visited;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        StringTokenizer st = null;
 
        int N = Integer.parseInt(br.readLine()); // 컴퓨터 개수
        graph = new int[N + 1][N + 1];
        visited = new boolean[N + 1];
 
        int linkCnt = Integer.parseInt(br.readLine());
        for (int i = 0; i < linkCnt; i++) {
            st = new StringTokenizer(br.readLine());
            int from = Integer.parseInt(st.nextToken());
            int to = Integer.parseInt(st.nextToken());
 
            graph[from][to] = 1;
            graph[to][from] = 1;
        }
 
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(1);
        visited[1] = true;
        int count = 0;
 
        while (!queue.isEmpty()) {
            int cur = queue.poll();
 
            for (int i = 1; i < graph.length; i++) {
                if (graph[cur][i] == 1 && !visited[i]) {
                    visited[i] = true;
                    queue.offer(i);
                    count++;
                }
            }
        }
 
        System.out.println(count);
 
        bw.flush();
        br.close();
        bw.close();
    }
}
 
Colored by Color Scripter
cs

 

'Algorithm/Algorithm Problem' 카테고리의 다른 글
  • [백준 - JAVA] 4375번 : 1
  • [백준 - JAVA] 2470번 : 두 용액
s_y_130
s_y_130
  • s_y_130
    About SY
    s_y_130
  • 전체
    오늘
    어제
    • 분류 전체보기 (434)
      • JAVA (54)
        • 더 자바 8 (0)
        • JAVA (41)
        • JAVA (JVM) (13)
      • Computer Science (86)
        • CS Basic (7)
        • OOP (11)
        • Design Pattern (16)
        • Network (8)
        • HTTP (6)
        • WEB (22)
        • OS (16)
      • DataBase (29)
        • DB theory (15)
        • MySQL (14)
        • Redis (0)
      • Collection Framework (1)
        • 구현 (1)
      • Data Structure (14)
        • Linear (9)
        • Non-Linear (5)
      • Algorithm (19)
        • Basic (12)
        • 응용 (2)
        • 완전 탐색(Brute Force) (1)
        • 다익스트라 (1)
        • Algorithm Problem (3)
      • Spring (104)
        • 스프링 핵심 원리 - 기본편 (9)
        • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (7)
        • 스프링 MVC 2편 - 백엔드 웹 개발 핵심 기술 (11)
        • 스프링 DB 1편 - 데이터 접근 핵심 원리 (6)
        • 스프링 DB 2편 - 데이터 접근 활용 기술 (10)
        • 스프링 핵심 원리 - 고급편 (13)
        • 스프링 부트 - 핵심 원리와 활용 (9)
        • Spring Security 6.x (2)
        • Spring Batch (2)
        • Spring Cloud로 개발하는 MSA (1)
        • 재고시스템으로 알아보는 동시성이슈 해결방법 (4)
        • 개념 (27)
        • 테스트 (0)
        • Annotation (1)
        • Error Log (2)
      • TEST (0)
        • 부하 테스트 (0)
        • Practical Testing: 실용적인 테스트.. (0)
      • JPA (40)
        • 자바 ORM 표준 JPA 프로그래밍 (12)
        • 1편- 실전! 스프링 부트와 JPA 활용 (7)
        • 2편- 실전! 스프링 부트와 JPA 활용 (4)
        • 실전! 스프링 데이터 JPA (6)
        • 실전! Querydsl (6)
        • 개념 (5)
      • 백엔드 부트캠프[사전캠프] (35)
        • TIL (12)
        • 문제풀이 (23)
      • 백엔드 부트캠프 (3)
        • Calculator (3)
      • Open Source (0)
      • Book Study (1)
        • Morden Java in Action (1)
        • Real MySQL 8.0 Vol.1 (0)
        • TDD : By Example (0)
      • AWS (0)
        • EC2 (0)
      • git (2)
      • AI (22)
        • Machine Learning (17)
        • Deep Learning (0)
        • TensorFlow (1)
        • PyTorch (1)
        • YOLO (1)
        • Data Analysis (0)
        • Ai code Error (1)
        • Numpy (1)
      • MY (0)
      • WEB (15)
        • Django (3)
        • WEB 개념 (1)
        • React (1)
        • Maven (10)
      • Python (6)
      • 기초수학 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
s_y_130
[백준 - JAVA] 2606번 : 바이러스
상단으로

티스토리툴바