Skip to content

Commit 79bbbeb

Browse files
committed
[Gold I] Title: 도로검문, Time: 112 ms, Memory: 80044 KB -BaekjoonHub
1 parent 43bd914 commit 79bbbeb

2 files changed

Lines changed: 188 additions & 0 deletions

File tree

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# [Gold I] 도로검문 - 2307
2+
3+
[문제 링크](https://www.acmicpc.net/problem/2307)
4+
5+
### 성능 요약
6+
7+
메모리: 80044 KB, 시간: 112 ms
8+
9+
### 분류
10+
11+
그래프 이론, 최단 경로, 데이크스트라, 역추적
12+
13+
### 제출 일자
14+
15+
2025년 11월 17일 18:05:33
16+
17+
### 문제 설명
18+
19+
<p>그림 1은 어떤 도시의 주요 지점과 그 지점들 간의 이동시간을 나타낸 그래프이다. 그래프의 노드는 주요 지점을 나타내고 두 지점을 연결한 도로(에지)에 표시된 수는 그 도로로 이동할 때 걸리는 분 단위의 시간을 나타낸다. 두 지점 a와 b를 연결하는 도로는 도로(a,b)로 표시한다.</p>
20+
21+
<p style="text-align: center;"><img alt="" src="https://upload.acmicpc.net/9f97f43f-357d-4818-8f7e-47b6a34cc52b/-/preview/" style="width: 280px; height: 156px;"></p>
22+
23+
<p style="text-align: center;">그림 1</p>
24+
25+
<p>예를 들어 도로(1,2)와 도로(2,3)를 통하여 지점1에서 지점3으로 갈 때 걸리는 시간은 3분이다. 도로는 모두 양방향이라고 가정하므로 도로(a,b)와 도로(b,a)를 지날 때 걸리는 시간은 항상 같다고 한다.</p>
26+
27+
<p>어떤 범죄용의자가 입력 데이터에 표시된 도시로 진입하여 이 도시를 가장 빠른 시간 내에 빠져나가고자 한다. 그런데 이 사실을 알고 있는 경찰이 어떤 하나의 도로(에지)를 선택하여 이 도로에서 검문을 하려고 한다. 따라서 용의자는 이 도로를 피해서 가장 빠르게 도시를 탈출하고자 한다. 이 경우 경찰이 검문을 위하여 선택하는 도로에 따라서 용의자의 가장 빠른 탈출시간은 검문이 없을 때에 비하여 더 늘어날 수 있다.</p>
28+
29+
<p>문제는 도로검문을 통하여 얻을 수 있는 탈출의 최대 지연시간을 계산하는 것이다. 추가설명은 다음과 같다.</p>
30+
31+
<ol>
32+
<li>두 개의 지점을 직접 연결하는 도로가 있는 경우, 그 도로는 유일하다.</li>
33+
<li>도시의 지점(노드)은 1에서 N번까지 N개의 연속된 정수로 표시된다.</li>
34+
<li>용의자가 도시에 진입하는 지점은 항상 1번이고 도시를 빠져 나가기 위하여 최종적으로 도달해야하는 지점은 항상 N번 지점이다.</li>
35+
<li>용의자는 검문을 피해서 가장 빨리 도시를 빠져나가고자 하고, 경찰은 적절한 도로를 선택하여 이 용이자들의 탈출시간을 최대한 지연시키고자 한다.</li>
36+
<li>각 도시 지점 간을 이동하는 시간은 항상 양의 정수이다.</li>
37+
</ol>
38+
39+
<p>입력 도시의 도로망에 따라서 경찰이 어떤 도로를 막으면 용의자는 도시를 탈출하지 못할 수도 있다. 이 경우 검문으로 인하여 지연시킬 수 있는 탈출시간은 무한대이다. 이 경우에는 -1을 출력해야 한다.</p>
40+
41+
<p>그림 1에서 볼 때 검문이 없을 경우 용의자가 도시를 탈출하는데 걸리는 시간은 4분이다. 만일 경찰이 도로(4,3)을 막으면 그 탈출시간을 지연시킬 수 없으므로 지연시간은 0이다. 만일 도로(2,3)을 막으면, 용의자들이 가장 빠르게 탈출할 수 있는 시간은 5분이므로 탈출지연시간은 1분이고, 도로(3,6)을 막으면 탈출지연시간은 2분이다.</p>
42+
43+
<p>여러분은 입력 데이터에 표시된 도로망을 읽고, 경찰이 한 도로를 막고 검문함으로써 지연시킬 수 있는 최대시간을 정수로 출력하여야한다. 만일 지연효과가 없으면 0을 출력해야하고, 도시를 빠져나가지 못하게 만들 수 있으면(지연시간이 무한대) -1을 출력해야 한다.</p>
44+
45+
### 입력
46+
47+
<p>첫 줄에는 지점의 수를 나타내는 정수 N(6 ≤ N ≤ 1000)과 도로의 수 M(6 ≤ M ≤ 5000)이 주어진다. 그 다음 이어 나오는 M개의 각 줄에는 도로(a, b)와 그 통과시간 t가 a b t 로 표시된다. 단 이 경우 a < b 이고 1 ≤ t ≤ 10000이다.</p>
48+
49+
### 출력
50+
51+
<p>경찰이 하나의 도로를 막음으로써 지연시킬 수 있는 최대 시간을 정수로 출력한다. (단, 그 지연시간이 무한대이면 -1을 출력해야 한다.)</p>
52+
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import Foundation
2+
3+
@inline(__always) func readInt() -> Int {
4+
var c = getchar()
5+
var n = 0
6+
while c == 10 || c == 32 { c = getchar() }
7+
var sign = 1
8+
if c == 45 { sign = -1; c = getchar() }
9+
while c >= 48 {
10+
n = n &* 10 &+ Int(c - 48)
11+
c = getchar()
12+
}
13+
return n * sign
14+
}
15+
16+
let N = readInt()
17+
let M = readInt()
18+
19+
var graph = Array(repeating: [(to: Int, cost: Int)](), count: N + 1)
20+
21+
var edges: [(u: Int, v: Int, w: Int)] = []
22+
edges.reserveCapacity(M)
23+
24+
for _ in 0..<M {
25+
let u = readInt()
26+
let v = readInt()
27+
let w = readInt()
28+
graph[u].append((v, w))
29+
graph[v].append((u, w))
30+
edges.append((u, v, w))
31+
}
32+
33+
struct PQ<T> {
34+
var heap: [T] = []
35+
let cmp: (T, T) -> Bool
36+
37+
mutating func push(_ x: T) {
38+
heap.append(x)
39+
var i = heap.count - 1
40+
while i > 0 {
41+
let p = (i - 1) >> 1
42+
if cmp(heap[i], heap[p]) {
43+
heap.swapAt(i, p)
44+
i = p
45+
} else { break }
46+
}
47+
}
48+
49+
mutating func pop() -> T? {
50+
if heap.isEmpty { return nil }
51+
heap.swapAt(0, heap.count - 1)
52+
let ret = heap.removeLast()
53+
var i = 0
54+
55+
while true {
56+
let l = i * 2 + 1
57+
let r = i * 2 + 2
58+
var smallest = i
59+
if l < heap.count && cmp(heap[l], heap[smallest]) { smallest = l }
60+
if r < heap.count && cmp(heap[r], heap[smallest]) { smallest = r }
61+
if smallest == i { break }
62+
heap.swapAt(i, smallest)
63+
i = smallest
64+
}
65+
return ret
66+
}
67+
68+
var isEmpty: Bool { heap.isEmpty }
69+
}
70+
71+
let INF = Int.max
72+
73+
func dijkstra(blockedEdge: (Int, Int)?) -> ([Int], [Int]) {
74+
var dist = Array(repeating: INF, count: N + 1)
75+
var prev = Array(repeating: -1, count: N + 1)
76+
77+
var pq = PQ<(Int, Int)>(heap: [], cmp: { $0.1 < $1.1 })
78+
dist[1] = 0
79+
pq.push((1, 0))
80+
81+
while !pq.isEmpty {
82+
let (x, cost) = pq.pop()!
83+
if dist[x] < cost { continue }
84+
85+
if x == N { break }
86+
87+
for e in graph[x] {
88+
let y = e.to
89+
let w = e.cost
90+
91+
// 차단 간선이면 skip
92+
if let block = blockedEdge {
93+
if (x == block.0 && y == block.1) || (x == block.1 && y == block.0) {
94+
continue
95+
}
96+
}
97+
98+
let nc = cost + w
99+
if nc < dist[y] {
100+
dist[y] = nc
101+
prev[y] = x
102+
pq.push((y, nc))
103+
}
104+
}
105+
}
106+
107+
return (dist, prev)
108+
}
109+
110+
let (dist0, prev0) = dijkstra(blockedEdge: nil)
111+
let base = dist0[N]
112+
113+
if base == INF {
114+
print(-1)
115+
exit(0)
116+
}
117+
118+
var pathEdges: [(Int, Int)] = []
119+
var cur = N
120+
while prev0[cur] != -1 {
121+
pathEdges.append((prev0[cur], cur))
122+
cur = prev0[cur]
123+
}
124+
125+
var answer = 0
126+
for (a, b) in pathEdges {
127+
let (distX, _) = dijkstra(blockedEdge: (a, b))
128+
if distX[N] == INF {
129+
print(-1)
130+
exit(0)
131+
}
132+
let delay = distX[N] - base
133+
if delay > answer { answer = delay }
134+
}
135+
136+
print(answer)

0 commit comments

Comments
 (0)