Buggy python submission (verdict: Time Limit Exceeded):
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [(start_x, start_y, 0)] \
       + [tuple(map(int, input().split())) for i in range(n)] \
       + [(goal_x, goal_y, 0)]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[0]*(n+2) for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2)**(0.5) - sum_radius)
        graph[i][j] = cost
        graph[j][i] = cost

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
q = []
q.append((0, 0))
distance[0] = 0
while q:
    here, c = heapq.heappop(q)
    if distance[here] < c:
        continue
    for t, cost in enumerate(graph[here]):
        if distance[here] + cost < distance[t]:
            distance[t] = distance[here] + cost
            heapq.heappush(q, (t, distance[t]))
            
print(distance[n+1])

Fixed submission:
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [(start_x, start_y, 0)] \
       + [tuple(map(int, input().split())) for i in range(n)] \
       + [(goal_x, goal_y, 0)]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[0]*(n+2) for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2)**(0.5) - sum_radius)
        graph[i][j] = cost
        graph[j][i] = cost
        graph = tuple(graph)

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
used = [False]*(n+2)
distance[0] = 0

while True:
    v = -1
    for u in range(n+2):
        if not used[u] and (v == -1 or distance[u] < distance[v]):
            v = u
    if v == -1:
        break
    used[v] = True
    for u in range(n+2):
        distance[u] = min(distance[u], distance[v] + graph[v][u])
            
print(distance[n+1])

Buggy python submission (verdict: Time Limit Exceeded):
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [(start_x, start_y, 0)] \
       + [tuple(map(int, input().split())) for i in range(n)] \
       + [(goal_x, goal_y, 0)]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[] for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2 )**(0.5) - sum_radius) 
        graph[i].append((j, cost))
        if i != j:
            graph[j].append((i, cost))

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
q = []
q.append((0, 0))
distance[0] = 0
while q:
    here, c = heapq.heappop(q)
    if distance[here] < c:
        continue
    for t, cost in graph[here]:
        if distance[here] + cost < distance[t]:
            distance[t] = distance[here] + cost
            heapq.heappush(q, (t, distance[t]))
            
print(distance[n+1])

Fixed submission:
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [(start_x, start_y, 0)] \
       + [tuple(map(int, input().split())) for i in range(n)] \
       + [(goal_x, goal_y, 0)]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[0]*(n+2) for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2)**(0.5) - sum_radius)
        graph[i][j] = cost
        graph[j][i] = cost
        graph = tuple(graph)

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
used = [False]*(n+2)
distance[0] = 0

while True:
    v = -1
    for u in range(n+2):
        if not used[u] and (v == -1 or distance[u] < distance[v]):
            v = u
    if v == -1:
        break
    used[v] = True
    for u in range(n+2):
        distance[u] = min(distance[u], distance[v] + graph[v][u])
            
print(distance[n+1])

Buggy python submission (verdict: Time Limit Exceeded):
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [[start_x, start_y, 0]] \
       + [list(map(int, input().split())) for i in range(n)] \
       + [[goal_x, goal_y, 0]]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[] for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2 )**(0.5) - sum_radius) 
        graph[i].append([j, cost])
        if i != j:
            graph[j].append([i, cost])

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
q = []
q.append([0,0])
distance[0] = 0
while q:
    here, c = heapq.heappop(q)
    if distance[here] < c:
        continue
    for t, cost in graph[here]:
        if distance[here] + cost < distance[t]:
            distance[t] = distance[here] + cost
            heapq.heappush(q, [t, distance[t]])
            
print(distance[n+1])

Fixed submission:
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [(start_x, start_y, 0)] \
       + [tuple(map(int, input().split())) for i in range(n)] \
       + [(goal_x, goal_y, 0)]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[0]*(n+2) for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2)**(0.5) - sum_radius)
        graph[i][j] = cost
        graph[j][i] = cost
        graph = tuple(graph)

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
used = [False]*(n+2)
distance[0] = 0

while True:
    v = -1
    for u in range(n+2):
        if not used[u] and (v == -1 or distance[u] < distance[v]):
            v = u
    if v == -1:
        break
    used[v] = True
    for u in range(n+2):
        distance[u] = min(distance[u], distance[v] + graph[v][u])
            
print(distance[n+1])

Buggy python submission (verdict: Time Limit Exceeded):
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [[start_x, start_y, 0]] \
       + [list(map(int, input().split())) for i in range(n)] \
       + [[goal_x, goal_y, 0]]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[] for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2 )**(0.5) - sum_radius) 
        graph[i].append([j, cost])
        if i != j:
            graph[j].append([i, cost])

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
q = []
q.append([0,0])
distance[0] = 0
while q:
    here, c = heapq.heappop(q)
    if distance[here] < c:
        continue
    for t, cost in graph[here]:
        if distance[here] + cost < distance[t]:
            distance[t] = distance[here] + cost
            heapq.heappush(q, [t, distance[t]])
            
print(distance[n+1])

Fixed submission:
start_x, start_y, goal_x, goal_y = map(int, input().split())
n = int(input())
info = [(start_x, start_y, 0)] \
       + [tuple(map(int, input().split())) for i in range(n)] \
       + [(goal_x, goal_y, 0)]

#i番目のバリアからj番目のバリアまでの移動について、
#受ける光線量を辺の重みとしてグラフを構築する(O(N^2))
graph = [[0]*(n+2) for i in range(n+2)]
for i in range(n+2):
    for j in range(i,n+2):
        diff_x = info[i][0] - info[j][0]
        diff_y = info[i][1] - info[j][1]
        sum_radius = info[i][2] + info[j][2]
        cost = max(0, ((diff_x)**2 + (diff_y)**2)**(0.5) - sum_radius)
        graph[i][j] = cost
        graph[j][i] = cost
        graph = tuple(graph)

#ダイクストラ法でstartからgoalまでの最短距離を求める

import heapq
distance = [float("inf")]*(n+2)
used = [False]*(n+2)
distance[0] = 0

while True:
    v = -1
    for u in range(n+2):
        if not used[u] and (v == -1 or distance[u] < distance[v]):
            v = u
    if v == -1:
        break
    used[v] = True
    for u in range(n+2):
        distance[u] = min(distance[u], distance[v] + graph[v][u])
            
print(distance[n+1])