C - 避難経路 / Evacuation Route Editorial by admin
gemini-3.5-flash-thinkingOverview
This problem asks for the minimum number of turns required for multiple evacuees (starting points) to reach the emergency exit \(T\) (goal point) while avoiding rooms on fire (obstacles). The time until all evacuees complete their evacuation is the maximum of the time it takes each evacuee to reach the emergency exit.
Analysis
1. Independence of Evacuees
From the problem statement, “the actions of each evacuee do not affect each other.” Therefore, we can independently calculate “how many turns it takes to reach the emergency exit \(T\)” for each evacuee, and then find the maximum among them.
2. Handling Rooms on Fire
Entering a room on fire causes an evacuee to be eliminated. Therefore, rooms on fire can be treated as “impassable obstacles (walls).”
Additionally, if an evacuee’s initial position is already a room on fire, they are immediately eliminated at the start of the simulation, making full evacuation impossible (the answer is -1).
3. Naive Approach and Optimization
What happens if we find the shortest path from each evacuee’s starting point \(S_i\) to the emergency exit \(T\) using breadth-first search (BFS) for each evacuee? The number of evacuees \(K\), rooms \(N\), and corridors \(M\) can each be up to \(2 \times 10^5\). If we perform BFS for each evacuee, the worst-case time complexity becomes \(O(K(N + M))\), which will not fit within the time limit (TLE).
Here, we apply the reverse thinking of “searching backwards from the goal.” While there are \(K\) starting points, there is only one goal point (emergency exit \(T\)). By performing BFS just once starting from the emergency exit \(T\) while avoiding rooms on fire, we can compute the shortest distance from all rooms to \(T\) in \(O(N + M)\) at once.
Algorithm
Initial Check: Determine whether any evacuee’s initial position \(S_i\) is a room on fire \(P_j\). If so, immediately output
-1as evacuation is impossible and terminate.Reverse BFS (Breadth-First Search): Perform BFS using a queue starting from the emergency exit \(T\).
- Initialize the distance array
distwith \(-1\), and setdist[T] = 0. - Add \(T\) to the queue.
- Dequeue a room \(u\), and for each adjacent room \(v\), check the following:
- Room \(v\) is not on fire.
- Room \(v\) has not been visited (
dist[v] == -1). - If the conditions are met, update
dist[v] = dist[u] + 1and add \(v\) to the queue.
- Initialize the distance array
Computing the Answer: For each evacuee’s initial position \(S_i\), check
dist[S_i].- If
dist[S_i] == -1for even one evacuee, that evacuee cannot reach the emergency exit, so output-1. - If all evacuees can reach the exit, the maximum of
dist[S_i]is the required minimum number of turns.
- If
Complexity
Time Complexity: \(O(N + M + K)\)
- Building the graph takes \(O(M)\), and recording fire positions takes \(O(Q)\).
- BFS from the emergency exit \(T\) traverses each vertex and each edge at most once, so it is \(O(N + M)\).
- Checking each evacuee’s initial position and computing the maximum takes \(O(K)\).
- Overall, this is \(O(N + M + K)\), which is sufficiently fast for the time limit.
Space Complexity: \(O(N + M)\)
- The adjacency list representing the graph uses \(O(N + M)\), and the distance array
distand fire flag array use \(O(N)\) of memory.
- The adjacency list representing the graph uses \(O(N + M)\), and the distance array
Implementation Notes
Case Where Initial Position is the Goal: An evacuee who is already at the emergency exit \(T\) completes evacuation in 0 turns. Since the BFS initial condition sets
dist[T] = 0, this case is handled correctly without any special treatment.Fast I/O: In Python, since the number of inputs is large, reading all input at once using
sys.stdin.read().split()can reduce I/O overhead.Source Code
import sys
from collections import deque
def solve():
input_data = sys.stdin.read().split()
if not input_data:
return
N = int(input_data[0])
M = int(input_data[1])
K = int(input_data[2])
Q = int(input_data[3])
T = int(input_data[4])
adj = [[] for _ in range(N + 1)]
idx = 5
for _ in range(M):
u = int(input_data[idx])
v = int(input_data[idx + 1])
adj[u].append(v)
adj[v].append(u)
idx += 2
S = [int(x) for x in input_data[idx : idx + K]]
idx += K
fire = [False] * (N + 1)
for _ in range(Q):
p = int(input_data[idx])
fire[p] = True
idx += 1
# 初期位置が火災の部屋である避難者がいるかチェック
for s in S:
if fire[s]:
print(-1)
return
# TからBFSで最短経路を求める
dist = [-1] * (N + 1)
dist[T] = 0
queue = deque([T])
while queue:
u = queue.popleft()
d = dist[u]
for v in adj[u]:
if not fire[v] and dist[v] == -1:
dist[v] = d + 1
queue.append(v)
# 各避難者の最短ターンの最大値を求める
ans = 0
for s in S:
if dist[s] == -1:
print(-1)
return
if dist[s] > ans:
ans = dist[s]
print(ans)
if __name__ == "__main__":
solve()
This editorial was generated by gemini-3.5-flash-thinking.
posted:
last update: