C - うわさの伝播 / Spread of Rumors Editorial by admin
GPT 5.4 HighOverview
If we consider people as vertices and communication methods as directed edges, this problem becomes “finding the shortest distance from the starting point \(S\) to each vertex.” The earliest day each person learns the rumor equals the shortest edge count from \(S\) to that person, so if everyone can be reached, the answer is the maximum of these values; if someone cannot be reached, the answer is \(-1\).
Analysis
The rumor spreads from people who know it on a given day to their neighbors on the next day. In other words,
- Exactly 1 edge is traversed per day
- The earliest day a person first receives the rumor is the “minimum number of edges” from \(S\) to that person
For example, if we have edges:
- \(S \to A\)
- \(A \to B\)
- \(S \to C\)
then:
- \(S\) knows on day \(0\)
- \(A, C\) know on day \(1\)
- \(B\) knows on day \(2\)
This is exactly the shortest distance from the starting point \(S\).
Key Insight
In this problem, edges have no weights, and every communication method takes “1 day” to deliver. Therefore, what we need is the shortest distance in an unweighted directed graph, which can be computed using BFS (Breadth-First Search).
Why a Naive Approach Is Too Slow
“Simulating, for each day, the spread from all people who currently know the rumor” is correct in principle. However, depending on the implementation, it may repeatedly examine all vertices or all edges every day, resulting in extremely slow worst-case performance.
Also, DFS (Depth-First Search) does not guarantee that the first path found is the shortest, so it is not suitable for correctly finding the earliest day each person learns the rumor.
How to Solve It
BFS explores in the order “vertices at distance \(0\) → vertices at distance \(1\) → vertices at distance \(2\) …”. Therefore, the distance when each vertex is first reached is the shortest distance to that vertex.
If we denote this shortest distance as dist[i], then:
- If
dist[i] = -1, the rumor never reaches that person - If everyone is reached, the earliest day everyone knows is \(\max_i dist[i]\)
Algorithm
- Build an adjacency list with people as vertices and communication methods as directed edges.
- Initialize the array
distto-1. - Set
dist[S] = 0for the starting pointSand enqueue it. - Perform BFS:
- Dequeue a vertex
u - For each vertex
vreachable fromu, if it is still unvisited:dist[v] = dist[u] + 1- Enqueue
v
- Dequeue a vertex
- After BFS completes:
- If there is even one person with
dist[i] = -1, output-1 - Otherwise, output the maximum value of
dist
- If there is even one person with
Why This Is Correct
- Since the rumor traverses exactly 1 edge per day, the earliest day it reaches a person is the shortest edge count.
- BFS explores in order of increasing edge count, so
dist[i]equals the shortest edge count from \(S\) to \(i\). - The day everyone knows the rumor is the day it reaches the last person. Therefore, the answer is the maximum of the shortest distances.
- If there is an unreachable person, the rumor will never spread to everyone.
Complexity
- Time complexity: \(O(N + M)\)
- Space complexity: \(O(N + M)\)
Implementation Notes
The graph is a directed graph, so only add edges in the direction
u -> v.Since we are finding shortest distances, use BFS with a queue.
Initializing
distto-1is convenient because it allows a single array to serve both purposes:- Checking whether a vertex has been reached
- Recording the number of days to reach it
At the end, by examining
dist, if any person is unreachable, we can immediately output-1.Source Code
import sys
from collections import deque
def main():
input = sys.stdin.readline
N, M, S = map(int, input().split())
graph = [[] for _ in range(N + 1)]
for _ in range(M):
u, v = map(int, input().split())
graph[u].append(v)
dist = [-1] * (N + 1)
dist[S] = 0
q = deque([S])
while q:
u = q.popleft()
du = dist[u]
for v in graph[u]:
if dist[v] == -1:
dist[v] = du + 1
q.append(v)
ans = 0
for i in range(1, N + 1):
if dist[i] == -1:
print(-1)
return
if dist[i] > ans:
ans = dist[i]
print(ans)
if __name__ == "__main__":
main()
This editorial was generated by gpt-5.4-high.
posted:
last update: