Problem:

Problem E: Light

Problem

$W \times H$ の二次元のマス上に$N$個の街灯がある。

がっちょ君は$(1,1)$からスタートして$(W,H)$に行きたい。

がっちょ君は暗いところが怖いので、街灯により明るくなっているマスしか歩きたくない。

最初、すべての街灯はその街灯のあるマスのみを明るくしている。

そこで、がっちょ君は好きな街灯$i$に対してコスト$r_i$を設定することにした。なお、コストを設定しない街灯があってもよい。

街灯$i$はコスト$r_i$を消費することにより、その街灯を中心にマンハッタン距離で$r_i$以内の範囲を明るくすることができる。ただしコストは正の整数とする。

がっちょ君は上下左右のいずれかの方向に隣接するマスに移動する事ができる。

がっちょ君は$r_i$の合計値を最小になるように設定することにした。そのときの合計値を求めよ。

2つの地点 $(a,b)$ と $(c,d)$ 間のマンハッタン距離は $|a−c|$+$|b−d|$ で表される。

Input

入力は以下の形式で与えられる。

$W$ $H$ $N$
$x_1$ $y_1$
...
$x_N$ $y_N$

  入力はすべて整数で与えられる。

  1行目に$W$と$H$と$N$が空白区切りで与えられる。

  続く$N$行に街灯$i$の座標$($$x_i$,$y_i$$)$が空白区切りで与えられる。

Constraints

入力は以下の条件を満たす。

$1 \leq W \leq 500$

$1 \leq H \leq 500$

$1 \leq N \leq 100$

$1 \leq N \leq W \times H$

$1 \leq $$x_i$$ \leq W$

$1 \leq $$y_i$$ \leq H$

同じ座標に複数の街灯はない

Output

$r_i$の合計値の最小値を1行に出力せよ。

Sample Input 1

10 10 1
6 6

Sample Output 1

10

Sample Input 2

5 10 3
3 9
2 8
5 1

Sample Output 2

8

Sample Input 3

1 1 1
1 1

Sample Output 3

0



Sample input:
10 10 1
6 6


Sample output:
10

Submission status: Wrong Answer

Solution code:
import bisect
from collections import deque

W,H,N = map(int,input().split())
src = [tuple(map(lambda x:int(x)-1,input().split())) for i in range(N)]
exist = [[0 for j in range(W)] for i in range(H)]
pos = set()
for x,y in src:
    exist[y][x] = 1
    pos.add(y+x)

def bfs(sx,sy,gx,gy):
    visited = [[0 for j in range(W)] for i in range(H)]
    q = deque([(0,sx,sy)])
    dxs = [1,0,-1,0]
    dys = [0,1,0,-1]
    ret = 0
    while q:
        d,x,y = q.popleft()
        ret = max(ret, d)
        if (x,y) == (gx,gy):
            break
        for dx,dy in zip(dxs,dys):
            nx,ny = x+dx, y+dy
            if not(0 <= nx < W) or not(0 <= ny < H): continue
            if not exist[ny][nx] or visited[ny][nx]: continue
            q.append((d+1,nx,ny))
            visited[ny][nx] = 1
    return ret

a = bfs(0,0,W-1,H-1)
b = H+W-2 - bfs(W-1,H-1,0,0)

if a >= b:
    print(0)
    exit()

if (b-a)%2 == 0:
    m = (a+b)//2
    if m in pos:
        print(m-a)
        exit()
    m1 = m-1
    m2 = m+1
else:
    m1 = (a+b)//2
    m2 = m1+1

ans = m2
while m1 >= a or m2 <= b:
    if m1 in pos or m2 in pos:
        break
    m1 -= 1
    m2 += 1
    ans += 1
print(ans)

Submission status: Accepted

Solution code:
import heapq
class point:
    def __init__(self, total, use, place):
        self.total = total
        self.use = use
        self.place = place

    def __lt__(self, other):
        return self.total < other.total or (self.total == other.total and self.use > self.use)


w, h, n = map(int, input().split())
if w == h == 1:
    print(0)
    exit()
lights = [list(map(int, input().split())) for _ in range(n)]
que = []
mins = []
for i, j in enumerate(lights):
    dis = j[0] + j[1] - 2
    heapq.heappush(que, point(dis, dis, i))
    mins.append(point(dis, dis, i))
ans = 100000
while que:
    top = heapq.heappop(que)
    ans = min(ans, top.total + max(0, abs(w - lights[top.place][0]) + abs(h - lights[top.place][1]) - top.use))
    for i in range(len(lights)):
        dis = abs(lights[top.place][0] - lights[i][0]) + abs(lights[top.place][1] - lights[i][1]) - 1
        use = max(0, dis - top.use)
        total = top.total + use
        new = point(total, use, i)
        if mins[i] > new:
            mins[i] = new
            heapq.heappush(que, new)
print(ans)