Skip to content

Instantly share code, notes, and snippets.

@whatalnk
Last active October 5, 2017 11:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whatalnk/7fea8afc82ba0c874d99c3693839c03c to your computer and use it in GitHub Desktop.
Save whatalnk/7fea8afc82ba0c874d99c3693839c03c to your computer and use it in GitHub Desktop.
AtCoder ABC #020 C - 壁抜け
Inf = 2 << 31
H, W, T = gets.chomp.split(" ").map(&:to_i)
m = Array.new(H){Array.new(W)}
start = 0
goal = 0
H.times do |i|
row = gets.chomp.split("")
W.times do |j|
m[i][j] = row[j]
if row[j] == "S"
# flatten matrix indices
start = i * W + j
elsif row[j] == "G"
goal = i * W + j
end
end
end
edge = Struct.new("Edge", :from, :to, :cost)
# four adjacent
d = [[0, -1], [1, 0], [0, 1], [-1, 0]]
low = 1
high = T
while true
# binary search
wt = (low + high) / 2
# make graph from matrix
es = Array.new()
H.times do |i|
W.times do |j|
from = i * W + j
d.each do |dx, dy|
ny = i + dy
nx = j + dx
if nx >= 0 && nx < W && ny >= 0 && ny < H
to = ny * W + nx
if m[ny][nx] == "#"
cost = wt
else
cost = 1
end
e = edge.new(from, to, cost)
es << e
end
end
end
end
# Bellman-Ford
dist = Array.new(H * W, Inf)
dist[start] = 0
while true
update = false
es.size.times do |i|
e = es[i]
if (dist[e.from] != Inf) && (dist[e.to] > dist[e.from] + e.cost)
dist[e.to] = dist[e.from] + e.cost
update = true
end
end
break if !update
end
# end binary search
if high - low == 1 then
puts wt
exit
end
# update low or high
if dist[goal] <= T
low = wt
else
high = wt
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment