This seems to be correct based on my tests. Multi-source BFS.
from collections import deque
# graph is an adjacency list, where graph[i] = set([j, k]) means
# that there's a road between i and j, i and k
# assumes that cities are labeled from [0, n - 1], and that
# if j is in graph[i], then i is in graph[j] as well.
def nearestCityWithHospital(graph, hospitalCities):
n = len(graph)
bfs = deque((i, 0) for i in hospitalCities)
ret = [-1 for _ in range(n)]
while bfs:
city, distance = bfs.popleft()
if ret[city] != -1:
continue
ret[city] = distance
for conn in graph.get(city, set()):
bfs.append((conn, distance + 1))
return ret
### tests
m = {0: set([1, 2]), \
1: set([0]), \
2: set([0, 3]), \
3: set([2])}
print(nearestCityWithHospital(m, [0]))
print(nearestCityWithHospital(m, [2,3]))
print(nearestCityWithHospital(m, [1,3]))
print(nearestCityWithHospital(m, [0,1,2,3]))