Problem:


壁

２XXX年、突然出現した天敵の侵入を防ぐために、人類は壁を作りその中に逃げ込んだ。その結果、人類の活動領域はその壁で囲まれた範囲に限定されてしまった。この領域は、上空から見ると W &times H の長方形である。領域内部には x 軸あるいは y 軸に対して平行な壁がいくつか設置されている。活動領域の例を下図に示す。

人類は活動領域内を自由に移動することができるが、壁を越えるためには一定量の資源を消費しなければならない。ただし、壁を越えることはできるが（図中の (1)）、壁の交点を越えること (2)、壁や活動領域の境界の上を移動すること (3)、活動領域外に出ること (4) はできない。

領域内部の壁の情報といくつかの始点と終点の組を入力し、始点から終点へ移動するために越えなければならない壁の数の最小値を計算するプログラムを作成しなさい。ただし、壁は幅のない線分とします。

入力

入力は１つのデータセットからなる。入力データは以下の形式で与えられる。

W H M
px1 py1 qx1 qy1
px2 py2 qx2 qy2
:
pxM pyM qxM qyM
Q
sx1 sy1 gx1 gy1
sx2 sy2 gx2 gy2
:
sxQ syQ gxQ gyQ

1行目に領域の横の長さと縦の長さを表す整数 W, H (2 ≤ W,H ≤ 1,000,000,000) と壁の数 M (0 ≤ M ≤ 100) が与えられる。

続く M 行に壁を表す線分の情報が与えられる。各行に与えられる４つの整数 pxi, pyi, qxi, qyi (0 ≤ pxi, qxi ≤ W, 0 ≤ pyi, qyi ≤ H) はそれぞれ i 番目の線分の端点の x 座標、y 座標、もうひとつの端点の x 座標、y 座標を表す。

続く1行に質問の数 Q (1 ≤ Q ≤ 100) が与えられる。続く Q 行に各質問が与えられる。各質問に含まれる４つの整数 sxi, syi, gxi, gyi (0 < sxi, gxi < W, 0 < syi, gyi < H) はそれぞれ始点の x 座標、y 座標、終点の x 座標、y 座標を表す。

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

 各線分は x 軸あるいは y 軸に対して平行であり、長さは1以上である。

 ２つの互いに平行な線分が同じ点あるいは線分を共有することはない。

 スタート地点、ゴール地点は壁上にあることはない。

 どの線分も活動領域の境界と線分を共有することはない。

出力

質問ごとに、壁を越える回数の最小値を出力する。

入出力例

入力例 1

5 6 5
0 2 5 2
0 3 5 3
0 4 3 4
1 4 1 6
3 0 3 6
2
2 5 4 1
2 5 4 5

出力例 1

3
1

入力例 2

4 4 0
1
1 1 2 2

出力例 2

0

入力例 3

4 7 3
0 2 2 2
3 3 4 3
0 5 4 5
3
1 1 1 3
1 1 1 4
1 1 1 6

出力例 3

0
0
1



Sample input:
5 6 5
0 2 5 2
0 3 5 3
0 4 3 4
1 4 1 6
3 0 3 6
2
2 5 4 1
2 5 4 5


Sample output:
3
1

Submission status: Accepted

Solution code:
from collections import defaultdict, deque
from bisect import bisect
W, H, M = map(int, input().split())
L = [list(map(int, input().split())) for i in range(M)]

XS = set([0, W])
YS = set([0, H])

for px, py, qx, qy in L:
    XS.add(px); XS.add(qx)
    YS.add(py); YS.add(qy)

X0 = sorted(XS)
Y0 = sorted(YS)

def convert(X0):
    mp = {}
    prv = -1
    cur = 0
    for x in X0:
        mp[x] = cur
        cur += 2
        prv = x
    cur -= 1
    return mp, cur

XM, X = convert(X0)
YM, Y = convert(Y0)

C = [[0]*X for i in range(Y)]
D = [[-1]*X for i in range(Y)]
for i in range(Y):
    C[i][0] = C[i][X-1] = 1
for i in range(X):
    C[0][i] = C[Y-1][i] = 1
for px, py, qx, qy in L:
    if px == qx:
        if not py < qy:
            py, qy = qy, py
        x0 = XM[px]
        y0 = YM[py]; y1 = YM[qy]
        for i in range(y0, y1+1):
            C[i][x0] = 1
    else:
        if not px < qx:
            px, qx = qx, px
        x0 = XM[px]; x1 = XM[qx]
        y0 = YM[py]
        for i in range(x0, x1+1):
            C[y0][i] = 1

dd = ((-1, 0), (0, -1), (1, 0), (0, 1))
que = deque()
cur = 0
for i in range(Y):
    for j in range(X):
        if C[i][j] or D[i][j] != -1:
            continue
        D[i][j] = cur
        que.append((j, i))
        while que:
            x, y = que.popleft()
            for dx, dy in dd:
                nx = x + dx; ny = y + dy
                if C[ny][nx] or D[ny][nx] != -1:
                    continue
                D[ny][nx] = cur
                que.append((nx, ny))
        cur += 1

N = cur
INF = 10**9
G = [[] for i in range(N)]
for i in range(1, Y-1):
    for j in range(1, X-1):
        a = D[i-1][j]; b = D[i+1][j]
        if a != -1 != b != a:
            G[a].append(b)
            G[b].append(a)
        a = D[i][j-1]; b = D[i][j+1]
        if a != -1 != b != a:
            G[a].append(b)
            G[b].append(a)

Q = int(input())
for i in range(Q):
    sx, sy, gx, gy = map(int, input().split())
    x0 = (bisect(X0, sx)-1)*2+1; y0 = (bisect(Y0, sy-1)-1)*2+1
    x1 = (bisect(X0, gx)-1)*2+1; y1 = (bisect(Y0, gy)-1)*2+1
    assert D[y0][x0] != -1 and D[y1][x1] != -1
    s = D[y0][x0]; t = D[y1][x1]
    que = deque([s])
    U = [-1]*N
    U[s] = 0
    while que:
        v = que.popleft()
        d = U[v]
        for w in G[v]:
            if U[w] != -1:
                continue
            U[w] = d+1
            que.append(w)
    print(U[t])