문제 링크
- http://icpc.me/18941
사용 알고리즘
- 듀얼 그래프
풀이
문제를 한 문장으로 요약하면 Online Decremental Dynamic Connectivity in Planar Graph입니다.
간선을 끊는 쿼리를 먼저 생각해봅시다.
평면 그래프에서는 $V-E+F = C+1$가 성립합니다. 간선을 하나 끊으면 E가 1만큼 감소합니다. 이때 $C$가 증가하기 위해서는 $V, F$ 값에 변동이 없어야 합니다. $V$의 값은 변하지 않으므로 $F$의 값만 봐주면 됩니다.
즉, 간선 하나를 끊었을 때 face의 개수가 줄어든다면 컴포넌트가 분리되지 않은 것이고, face의 개수가 변하지 않았다면 컴포넌트가 분리된 것입니다. face의 개수 변화는 Dual Graph를 이용해 관리해줄 수 있습니다.
두 정점 $u, v$를 간선이 없어지면서 컴포넌트가 분리되었다면 $u$를 포함하는 컴포넌트와 $v$를 포함하는 컴포넌트로 나뉘게 될텐데, small to large처럼 둘 중 크기가 더 작은 쪽에만 색깔을 다시 칠해주면 모든 쿼리에서 최대 $O(N \log N)$번만 색칠하게 됩니다.
즉, 간선을 끊는 쿼리는 amortized $O(\log N)$에 처리할 수 있습니다.
두 정점 $u, v$가 연결되었는지 확인하는 것은 정점의 색깔만 봐주면 되므로 $O(1)$에 처리할 수 있습니다.
크기가 더 작은 쪽에만 색을 칠해주기 위해서는 두 컴포넌트의 크기를 알아야 합니다.
단순하게 DFS/BFS를 돌리면 $O(N^2)$ 당연히 안 되고, 스택/큐에 정점을 하나씩 추가하면서 신중하게 잘 구현해야 합니다.
크기 구할 때 쿼리당 $O(N)$에 구하고 색칠하는 것은 amortized $O(log N)$만에 하는 풀이를 저격하는 데이터가 Star Graph밖에 없기 때문에, 트리일 때는 KOI16 고등부 트리처럼 HLD로 예외처리해주는 풀이가 통과됩니다.
데이터 추가 요청을 넣어놓은 상태입니다.
전체 코드
1 |
|