Skip to content

Commit 0ead5e3

Browse files
committed
[Gold IV] Title: Defend the CTP!!!, Time: 396 ms, Memory: 155152 KB -BaekjoonHub
1 parent e6f18cd commit 0ead5e3

2 files changed

Lines changed: 164 additions & 0 deletions

File tree

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import Foundation
2+
3+
final class FastScanner {
4+
private var data: [UInt8] = Array(FileHandle.standardInput.readDataToEndOfFile()) + [0]
5+
private var idx: Int = 0
6+
7+
func readInt() -> Int {
8+
var num = 0
9+
var sign = 1
10+
while data[idx] == 10 || data[idx] == 13 || data[idx] == 32 { idx += 1 }
11+
if data[idx] == 45 { sign = -1; idx += 1 }
12+
while data[idx] >= 48 {
13+
num = num * 10 + Int(data[idx] - 48)
14+
idx += 1
15+
}
16+
return num * sign
17+
}
18+
}
19+
20+
let scanner = FastScanner()
21+
22+
let N = scanner.readInt()
23+
let M = scanner.readInt()
24+
25+
var graph = Array(repeating: [Int](), count: N + 1)
26+
var rgraph = Array(repeating: [Int](), count: N + 1)
27+
28+
for _ in 0..<M {
29+
let x = scanner.readInt()
30+
let y = scanner.readInt()
31+
graph[x].append(y)
32+
rgraph[y].append(x)
33+
}
34+
35+
var visited = Array(repeating: false, count: N + 1)
36+
var order = [Int]()
37+
38+
func dfs1(_ u: Int) {
39+
visited[u] = true
40+
for v in graph[u] {
41+
if !visited[v] {
42+
dfs1(v)
43+
}
44+
}
45+
order.append(u)
46+
}
47+
48+
for i in 1...N {
49+
if !visited[i] {
50+
dfs1(i)
51+
}
52+
}
53+
54+
var sccId = Array(repeating: 0, count: N + 1)
55+
var sccCount = 0
56+
57+
func dfs2(_ start: Int) {
58+
var stack = [start]
59+
sccId[start] = sccCount
60+
61+
while let u = stack.popLast() {
62+
for v in rgraph[u] {
63+
if sccId[v] == 0 {
64+
sccId[v] = sccCount
65+
stack.append(v)
66+
}
67+
}
68+
}
69+
}
70+
71+
for u in order.reversed() {
72+
if sccId[u] == 0 {
73+
sccCount += 1
74+
dfs2(u)
75+
}
76+
}
77+
78+
var dag = Array(repeating: Set<Int>(), count: sccCount + 1)
79+
var rdag = Array(repeating: Set<Int>(), count: sccCount + 1)
80+
81+
for u in 1...N {
82+
for v in graph[u] {
83+
let a = sccId[u]
84+
let b = sccId[v]
85+
if a != b {
86+
dag[a].insert(b)
87+
rdag[b].insert(a)
88+
}
89+
}
90+
}
91+
92+
let start = sccId[1]
93+
let end = sccId[N]
94+
95+
var fromStart = Array(repeating: false, count: sccCount + 1)
96+
var toEnd = Array(repeating: false, count: sccCount + 1)
97+
98+
func dfsReach(_ start: Int, _ g: [Set<Int>], _ visited: inout [Bool]) {
99+
var stack = [start]
100+
visited[start] = true
101+
102+
while let u = stack.popLast() {
103+
for v in g[u] {
104+
if !visited[v] {
105+
visited[v] = true
106+
stack.append(v)
107+
}
108+
}
109+
}
110+
}
111+
112+
dfsReach(start, dag, &fromStart)
113+
dfsReach(end, rdag, &toEnd)
114+
115+
let T = scanner.readInt()
116+
var output = ""
117+
118+
for _ in 0..<T {
119+
let c = scanner.readInt()
120+
let s = sccId[c]
121+
if fromStart[s] && toEnd[s] {
122+
output += "Defend the CTP\n"
123+
} else {
124+
output += "Destroyed the CTP\n"
125+
}
126+
}
127+
128+
print(output)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# [Gold IV] Defend the CTP!!! - 14615
2+
3+
[문제 링크](https://www.acmicpc.net/problem/14615)
4+
5+
### 성능 요약
6+
7+
메모리: 155152 KB, 시간: 396 ms
8+
9+
### 분류
10+
11+
그래프 이론, 그래프 탐색, 너비 우선 탐색, 깊이 우선 탐색
12+
13+
### 제출 일자
14+
15+
2026년 1월 18일 17:19:17
16+
17+
### 문제 설명
18+
19+
<p dir="ltr">지금으로부터 527년이 지난 서기 2544년, 항성 간 이동이 가능해진 인류는 태양계가 아닌 새로운 보금자리를 찾아 기술의 집약체인 CTP(Cho Technology Planet, 초 기술 행성)를 건설한다. 인공지능이 관리하는 CTP 안에서는 자연재해도 전쟁도 없었으며 많은 사람이 행복을 누리며 살아나갔다.</p>
20+
21+
<p dir="ltr">CTP에는 N개의 도시가 있는데 각각의 도시들은 1번부터 N번까지 고유한 번호를 가지고 있으며 각 도시들끼리는 매우 빠른 속도로 이동할 수 있는 튜브로 연결되어 있다. 단 튜브는 매우 빠른 속도로 이동해야 하기 때문에 한 방향으로만 이동을 할 수 있다. 즉 A도시에서 B도시로 이동하는 튜브가 있다고 해서 B도시에서 A도시로 이동하는 튜브가 항상 존재하는 것은 아니다. 또한 튜브 안에서는 매우 빠른 속도로 이동이 가능하기 때문에 두 도시가 아무리 멀리 떨어져 있어도 이동하는 시간은 무시할만큼 적게 든다.</p>
22+
23+
<p dir="ltr">모든 사람들의 유토피아 CTP는 어느 날 우주급 빌런 재유니스의 침공으로 건설 이래 최대 위기에 직면한다. 재유니스는 N개의 도시 중 한 도시에 CTP를 한 번에 파괴할 수 있는 위력의 반물질 폭탄을 설치하고 사라진다. CTP를 구하기 위해서는 반물질 폭탄을 N번 도시에 있는 항성 간 이동장치를 통해 블랙홀로 보내야 한다. 가장 이상적인 방법은 반물질 폭탄이 있는 도시에서 폭탄을 N번 도시로 보내면 되지만 폭탄은 일반 사람이 들기에 너무 무겁기에 1번 도시에 있는 슈퍼히어로 미노만이 들고 이동할 수 있다.</p>
24+
25+
<p dir="ltr">튜브의 이동속도는 매우 빠르기 때문에 미노가 1번 도시에서 반물질 폭탄이 있는 도시로 이동한 다음에 폭탄을 들고 다시 N번 도시로 이동할 수만 있다면 CTP를 구할 수 있다. 이동하는 과정에서 똑같은 튜브를 다시 사용할 수 있고 방문했던 도시를 또다시 방문할 수도 있다. 또한 이동경로의 길이 제한은 없다.</p>
26+
27+
<p>과연 슈퍼히어로 미노는 위기에 빠진 CTP를 구할 수 있을까? 입력으로는 T개의 시나리오가 주어진다. 시나리오마다 재유니스가 반물질 폭탄을 설치한 도시의 번호가 주어진다. 각각의 시나리오에 대해 슈퍼히어로 미노가 CTP를 지킬 수 있는지 알아보는 프로그램을 작성하자.</p>
28+
29+
### 입력
30+
31+
<p>첫 번째 줄에 N(3≤N≤100,000)과 M(1≤M≤1,000,000)이 주어진다. N은 CTP에 존재하는 도시의 개수를 의미하고 M은 CTP에 존재하는 튜브의 개수를 의미한다. 다음 M개의 줄에 걸쳐 X, Y(1≤X, Y≤N)가 주어지는데 X에서 Y로 이동할 수 있는 튜브가 있다는 뜻이다. 다음 줄에는 시나리오의 개수 T(1≤T≤100,000)가 주어진다. 다음 T개의 줄에 차례대로 C(2≤C≤N-1)가 주어지는데 이는 우주급 빌런 재유니스가 반물질 폭탄을 설치한 도시의 번호를 의미한다. 입/출력의 양이 많으므로 속도가 빠른 입/출력 함수를 사용하는것을 권장한다.</p>
32+
33+
### 출력
34+
35+
<p>T개의 줄에 걸쳐 CTP를 지킬 수 있는지 결과를 출력한다. 만약 CTP를 구할 방법이 없다면 “Destroyed the CTP”를 출력하고 슈퍼히어로 미노가 CTP를 구할 수 있다면 “Defend the CTP”를 출력한다. 모든 출력은 쌍따옴표를 제외하고 출력한다.</p>
36+

0 commit comments

Comments
 (0)