처음에는 문제 내용을 제대로 이해하지 못해서 난처했는데, 결국 간단히 정리하면 주어진 네트워크에서 임의의 한 정점을 제거했을 때 최대 몇 개의 부분으로 나눠지는지를 구하는 문제이다.
트리에서의 다이나믹 프로그래밍(Dynamic Programming)으로 풀 수 있는 문제인 줄 알았는데, 문제에서 ‘The network may contain cycles.’이라고 명시되어 있다. 그래서 주어지는 네트워크 그래프가 트리가 아닐 수 있으므로 다른 접근 방법이 필요해보였다.
단순히 DFS(Depth Frist Search)를 통해 어떤 cycle 내의 임의의 한 점을 제거한다고 해서 cycle이 무조건 두 개 이상의 부분으로 나눠진다고 보장할 수 없다. 따라서 단절점의 개념을 이용하면 문제를 풀 수 있을 것이다.
하나의 컴포넌트(Connected Component)로 이루어진 양방향(또는 무방향) 그래프에서 특정 정점을 제거했을 때 두 개 이상의 컴포넌트로 나눌 수 있을 때 그 정점이 단절점이다. 문제에서 주어진 그래프에서 단절점을 찾고, 그 중 하나를 제거했을 때 부분으로 나누어지는 컴포넌트 수를 구하면 될 것이다. 단절점이 아닌 정점을 제거하면 해당 정점이 속한 BCC(Biconnected Component)가 분리되지 않으므로 단절점에 관해서만 제거 시 몇 개의 부분으로 나누어지는지 확인하면 된다.
Tarjan’s Algorithm의 DFS 과정을 통해서 모든 정점을 방문해주는데, 그 중 방문 중인 현재 노드 now가 단절점일 때 해당 노드가 몇 개의 컴포넌트에 속하는지 구한다.
bccNum[i]: 정점 i가 속하는 BCC 개수
1) 단절점인 현재 노드 now가 root 노드가 아닐 때
bccNum[now] = (now 노드의 자식 노드와 묶이는 BCC 개수) + 1 ∵ 부모 노드와 묶이는 BCC도 추가해야 하므로 1을 더한다.
※ 현재 노드 now의 부모 노드가 두 개 이상일 수도 있지 않을까?
- Tarjan’s Algorithm의 실행 과정을 이해하면 방문 중인 노드의 부모 노드가 두 개 이상일 수가 없다. Cycle이 있는 그래프를 DFS 탐색할 때 방문 중인 노드의 부모 노드를 두 개 이상으로 판단하고 탐색하지 않는 것과 유사하다.
2) 단절점인 현재 노드 now가 root 노드일 때
bccNum[now] = now 노드의 자식 노드와 묶이는 BCC 개수
전체 그래프에서 모든 정점의 bccNum 중 가장 큰 값을 답으로 구한다.
ans = max(bccNum[i]) (단, 정점 i는 단절점, 1 ≤ i ≤ v)
주의할 점은 애초에 처음부터 둘 이상의 컴포넌트로 분리되어 있는 그래프가 네트워크로 주어질 수도 있다는 것이다.