문제: BOJ 12012 - Closing the Farm (Gold)
헛간을 하나씩 닫아가며(정점 삭제) 매 시점에 남은 헛간들이 모두 서로 도달 가능(완전 연결) 인지 판정하는 문제다. 정점 삭제는 온라인으로 다루기 까다롭지만, 닫는 순서를 뒤집으면 “여는 과정(정점 추가)” 이 되어 DSU로 깔끔하게 해결할 수 있다.
문제 정보
문제 링크: https://www.acmicpc.net/problem/12012
문제 요약:
- \(N\)개의 헛간과 \(M\)개의 무방향 길이 주어진다.
- 초기 상태(아무것도 닫히지 않음)와, 각 헛간을 하나씩 닫은 뒤마다 남은 헛간들이 완전 연결인지 “YES”/“NO"로 출력한다.
제한 조건:
- 시간 제한: 2초
- 메모리 제한: 512MB
- \(1 \le N, M \le 200{,}000\)
입출력 예제
입력 1:
| |
출력 1:
| |
접근 방식
핵심 관찰: “닫기”를 “열기”로 뒤집으면 DSU로 된다
정점을 하나씩 닫는 과정은 동적 연결성(정점 삭제)이라 직접 처리하기 어렵다. 하지만 닫는 순서가 미리 주어지므로 이를 역순으로 처리하면:
- 역순에서는 정점을 하나씩 연다(활성화).
- 새로 열린 정점 \(x\)는, 이미 열린 이웃 정점들과 간선으로 연결되어 있으므로 union 하면 된다.
이때 열린 정점들이 완전 연결인지 확인하는 조건은 다음과 같다:
- 현재 열린 정점 수를 \(K\)라고 하면,
- 새로 연 정점 \(x\)가 속한 DSU 컴포넌트 크기가 \(K\)이면 열린 정점들이 모두 한 컴포넌트 → “YES”
알고리즘 설계 (Mermaid Flowchart)
flowchart TD
A["입력 N,M 및 그래프 간선"] --> B["닫는 순서 close[1..N] 입력"]
B --> C["열림 배열 open[] 초기화DSU 초기화openCnt=0"]
C --> D["i=N..1 역순 반복"]
D --> E["x = close[i] 를 연다open[x]=true, openCnt++"]
E --> F["x의 이웃 y 중 open[y]=true 인 것들과 union(x,y)"]
F --> G{"DSU.size(x) == openCnt ?"}
G -- "Yes" --> H["ans[i] = YES"]
G -- "No" --> I["ans[i] = NO"]
H --> D
I --> D
복잡도 분석
| 항목 | 복잡도 | 비고 |
|---|---|---|
| 시간 복잡도 | \(O((N+M)\alpha(N))\) | 각 간선은 최대 2번 확인, DSU union/find |
| 공간 복잡도 | \(O(N+M)\) | 인접 리스트 + DSU + 열림 배열 |
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| 초기부터 비연결 | 1행이 “NO"일 수 있음 | 역순 결과를 그대로 출력하면 자동 처리 |
| N=1 | 열린 정점 수 1이면 항상 완전 연결 | openCnt와 size(x) 비교로 자연히 “YES” |
| 중복 union | 같은 컴포넌트를 여러 번 union 가능 | DSU에서 같은 대표면 무시 |
| 정점이 아직 닫혀있음 | 닫힌 정점과의 간선은 사용 불가 | open[y]인 이웃만 union |
구현 코드
C++
| |
![Featured image of post [Algorithm] C++ 백준 12012번: Closing the Farm (Gold)](/post/algorithm/2025-12-23-boj-12012-closing-the-farm-dsu-offline-cpp-solution/wordcloud_hu_4444f1c6c670f805.webp)
![[Algorithm] C++ 백준 9120번: Oulipo 다국어](/post/algorithm/2026-01-05-boj-9120-oulipo-multilingual-kmp-string-matching-cpp-solution/wordcloud_hu_a41b48d1fb03377b.webp)
![[Algorithm] C++ 백준 14289번: 본대 산책 3](/post/algorithm/2026-01-02-boj-14289-bondae-walk-3-matrix-exponentiation-cpp-solution/wordcloud_hu_d4b90edc889f3796.webp)
![[Algorithm] C++ 백준 12012번: Closing the Farm (Gold)](/post/algorithm/2025-12-23-boj-12012-closing-the-farm-dsu-offline-cpp-solution/wordcloud_hu_948e063ef28de048.webp)
![[Algorithm] C++ 백준 1258번: 문제 할당](/post/algorithm/2025-12-23-boj-1258-problem-assignment-hungarian-cpp-solution/wordcloud_hu_99f4e04a3660d804.webp)
![[Algorithm] C++ 백준 13028번: 민호의 소원](/post/algorithm/2025-12-22-boj-13028-minhos-wish-fenwick-offline-cpp-solution/wordcloud_hu_f31a7aa94b425a5c.webp)
![[Algorithm] C++ 백준 25172번: 꼼꼼한 쿠기의 졸업여행](/post/algorithm/2026-01-24-boj-25172-graduation-trip-dynamic-connectivity-dsu-offline-cpp-solution/wordcloud_hu_6a5672d9d17b4add.webp)
![[Algorithm] C++ 백준 17481번: 최애 정하기](/post/algorithm/2026-02-06-boj-17481-favorite-member-bipartite-matching-hopcroft-karp-cpp-solution/wordcloud_hu_44b3c5d534a357d8.webp)
![[Algorithm] C++ 백준 13232번: Domain clusters](/post/algorithm/2025-12-22-boj-13232-domain-clusters-scc-tarjan-cpp-solution/wordcloud_hu_a1e9324420b23710.webp)