Skip to content

Commit 7ec1998

Browse files
committed
[Gold III] Title: 선물 교환, Time: 476 ms, Memory: 121208 KB -BaekjoonHub
1 parent 4ea41aa commit 7ec1998

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# [Gold III] 선물 교환 - 1889
2+
3+
[문제 링크](https://www.acmicpc.net/problem/1889)
4+
5+
### 성능 요약
6+
7+
메모리: 121208 KB, 시간: 476 ms
8+
9+
### 분류
10+
11+
그래프 이론, 방향 비순환 그래프, 위상 정렬
12+
13+
### 제출 일자
14+
15+
2026년 2월 3일 19:33:21
16+
17+
### 문제 설명
18+
19+
<p>캠프의 마지막 날에 선물 교환 이벤트를 하려고 한다. 모든 학생들이 각자 두 개씩 선물을 준비해 와서 두 명의 친구에게 주는 것이다. 이벤트를 준비하던 중, 조교들은 이러한 이벤트가 불화를 일으킬 수 있음을 알게 되었다. 참석한 학생들 중 일부 학생들은 선물을 못 받거나 하나만 받게 되는 데 비해, 인기가 많은 학생들은 선물을 세 개 또는 그 이상 받게 되는 것이다.</p>
20+
21+
<p>그래서 조교들은 모든 학생들이 두 개의 선물을 주고, 또한 모든 학생들이 정확히 두 개의 선물만을 받도록 이벤트를 준비하고자 한다. 이를 위해 각각의 학생이 선물을 주고자 하는 두 명의 학생이 누구인지를 미리 알아내었다. 리스트를 살펴보던 조교들은, 몇 명의 학생을 추려 내면 모든 학생이 정확히 두 개의 선물을 받을 수 있다는 것을 알게 되었다.</p>
22+
23+
<p>참여한 모든 학생이 정확히 선물을 두 개씩 받도록 이벤트에 참여할 학생들을 결정하는 프로그램을 작성하시오. 단, 이벤트에 참여하는 학생의 수가 최대가 되도록 해야 한다.</p>
24+
25+
### 입력
26+
27+
<p>첫째 줄에 학생의 수 N(3 ≤ N ≤ 200,000)이 주어진다. 학생은 1부터 N까지 번호가 매겨진다. 이어서 다음 N개 줄에는 각 학생이 선물을 주고자 하는 두 학생의 번호가 빈 칸을 사이에 두고 주어진다. 자기 자신에게 선물을 주는 경우는 없으며, 두 사람의 번호는 항상 다르다.</p>
28+
29+
### 출력
30+
31+
<p>첫째 줄에 최대로 참여시킬 수 있는 학생의 수를 출력한다. 둘째 줄에는 참여할 학생들의 번호를 증가하는 순서대로 빈 칸을 사이에 두고 출력한다. 가능한 방법이 둘 이상인 경우 그 중 한 가지만 출력한다. 만일 한 명의 학생도 참여시킬 수 없는 경우 첫째 줄에 0만을 출력한다.</p>
32+
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import Foundation
2+
3+
let N = Int(readLine()!)!
4+
5+
var outGraph = [[Int]](repeating: [Int](), count: N+1)
6+
var inGraph = [[Int]](repeating: [Int](), count: N + 1)
7+
var presentCountList = [Int](repeating: 0, count: N+1)
8+
9+
for i in 1...N {
10+
let line = readLine()!.split { $0 == " " }.map { Int(String($0))! }
11+
outGraph[i].append(line[0])
12+
outGraph[i].append(line[1])
13+
inGraph[line[0]].append(i)
14+
inGraph[line[1]].append(i)
15+
presentCountList[line[0]] += 1
16+
presentCountList[line[1]] += 1
17+
}
18+
19+
bfs()
20+
21+
func bfs() {
22+
var queue = [Int]()
23+
var index = 0
24+
var isVisited = [Bool](repeating: false, count: N+1)
25+
for i in 1...N {
26+
if inGraph[i].count < 2 {
27+
queue.append(i)
28+
}
29+
}
30+
while queue.count > index {
31+
let currentNode = queue[index]
32+
if isVisited[currentNode] {
33+
index += 1
34+
continue
35+
}
36+
isVisited[currentNode] = true
37+
// 2개 미만의 선물을 받은 학생이 선물을 준 학생들의 선물갯수를 깎는다.
38+
for child in outGraph[currentNode] {
39+
presentCountList[child] -= 1
40+
if presentCountList[child] < 2 {
41+
queue.append(child)
42+
}
43+
}
44+
for parent in inGraph[currentNode] {
45+
queue.append(parent)
46+
}
47+
index += 1
48+
}
49+
var count = 0
50+
var answer = ""
51+
for i in 1...N {
52+
guard presentCountList[i] > 1 else { continue }
53+
count += 1
54+
answer += "\(i) "
55+
}
56+
print(count)
57+
if count > 0 {
58+
print(answer)
59+
}
60+
}

0 commit comments

Comments
 (0)