이번 문제는 백준의 골드 4 문제 민서의 응급 수술 문제이다.
문제를 한 번 차근차근 읽어보자.
대충 문제를 훑어보니, 뉴런들을 트리 형태로 연결하고 싶다고 한다.
그 말은, 시냅스들로 사이클 없이 모든 뉴런을 연결하고 싶다는 말이다.
사이클 없이 모두 연결된 트리..? 신장 트리 얘기인 것 같다.
다른 조건은 최대 100000개의 노드, 100000개의 간선이 주어진다.
조건만 보았을 땐, 신장 트리를 만드는 방법을 구현하는 것 같다.
그런데 조건에 중요한 부분이 하나 보인다. 시냅스를 제거할 수 있다. 라는 조건이 문제에 있는데,
그 말은 사이클이 존재할 때 시냅스를 제거해서도 트리를 만들 수 있다는 말이다.
즉, 사이클이 존재한다면 끊어내는 동작도 구현해야 한다는 말이다.
해당 동작을 어떻게 구현할 지가 관건일 것 같다.
Kruskal 알고리즘
우선, 기본적으로 신장 트리를 구현하는 알고리즘으로는 Kruskal 알고리즘을 사용하도록 할 것이다.
원래는 최소 신장 트리를 구하는 알고리즘이지만, 기본적인 원리로
신장 트리를 구할 수 있기 때문에 사용하도록 한다.
기본적으로 union 동작을 통해서 미완성 트리를 완성할 수 있다.
하지만 문제는 이미 사이클이 생겨버린 상태에서 어떻게 끊는가? 이다.
사이클 체크
사이클에 대한 검사는 어떤 두 노드의 부모를 검사했을 때,
두 노드가 같은 부모를 두고 있다면 union을 하면 사이클이 생긴다.
그래서 항상 사이클을 체크해서 사이클이 생기는 것을 방지하도록 한다.
최초에 간선을 입력받을 때, 사이클을 검사하여 가능성이 있으면 배제한다.
이 동작을 사이클을 끊는 것으로 간주하여 동작 횟수를 늘려준다.
이제 남은 일은 연결되지 않은 노드를 연결하는 것!
남은 노드 연결
남은 노드 중 연결되지 않은 노드는 어떤 상태일까?
연결이 되지 않았으므로 부모 노드가 자기 자신으로 설정되어 있을 것이다.
그럼 트리 배열을 돌아, 가장 처음 연결되지 않은 부분을 루트로 삼자.
마저 탐색하다 만나는 나머지 연결되지 않은 부분들을 모두 루트에 연결한다.
그렇다면 사이클 없이 모든 트리가 연결될 것이다.