문제: 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_c8c429e509db4b8a.png)
![[Algorithm] C++ 백준 12012번: Closing the Farm (Gold)](/post/algorithm/2025-12-23-boj-12012-closing-the-farm-dsu-offline-cpp-solution/wordcloud_hu_5a95d85e90d9352c.png)
![[Algorithm] C++ 백준 1258번: 문제 할당](/post/algorithm/2025-12-23-boj-1258-problem-assignment-hungarian-cpp-solution/wordcloud_hu_fb5f370a4bccc9ee.png)
![[Algorithm] C++ 백준 13028번: 민호의 소원](/post/algorithm/2025-12-22-boj-13028-minhos-wish-fenwick-offline-cpp-solution/wordcloud_hu_131d7568faac9120.png)
![[Algorithm] C++ 백준 13232번: Domain clusters](/post/algorithm/2025-12-22-boj-13232-domain-clusters-scc-tarjan-cpp-solution/wordcloud_hu_3a7a8d5f138b64d1.png)
![[Algorithm] C++ 백준 10050번: 블록](/post/algorithm/2025-12-20-boj-10050-block-cpp-solution/wordcloud_hu_ed188e3b2b566e60.png)
![[Algorithm] C++ 백준 1185번: 유럽여행](/post/algorithm/2025-12-19-boj-1185-europe-travel-mst-kruskal-cpp-solution/wordcloud_hu_a7973902548ef27b.png)
![[Algorithm] C++ 백준 2988번: 아보가드로](/post/algorithm/2025-12-19-boj-2988-avogadro-cpp-solution/wordcloud_hu_504f3f1bc728ef52.png)
![[Algorithm] C++ 백준 18473번 : Fast Spanning Tree](/post/algorithm/2025-08-12-boj-18473-fast-spanning-tree-cpp-solution/wordcloud_hu_4be2750cf9c8f501.png)