結果
| 問題 |
No.3351 Towering Tower
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-11 00:25:22 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 1,421 ms / 3,000 ms |
| コード長 | 3,165 bytes |
| コンパイル時間 | 319 ms |
| コンパイル使用メモリ | 82,104 KB |
| 実行使用メモリ | 90,628 KB |
| 最終ジャッジ日時 | 2025-11-13 21:16:24 |
| 合計ジャッジ時間 | 30,289 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 27 |
ソースコード
import sys
from collections import deque
input = sys.stdin.readline
INF = (1 << 61) + (1 << 31) - 1
def solve():
N, M = map(int, input().split())
H = list(map(int, input().split()))
H.append(0) # H[N] will be overwritten in loop
G = [[] for _ in range(N + 1)]
for _ in range(M):
U, V = map(int, input().split())
U -= 1
V -= 1
if V != N:
G[U].append(V)
G[V].append(U)
Hord = sorted([(H[i], i) for i in range(N)])
ans = 10**9 * N
ng = -1
def nminmax(fr, to, X):
if fr == N:
return (-100, INF)
if H[to] == H[fr]:
if H[fr] <= X:
return (-100, INF)
else:
return (INF, -100)
elif H[to] > H[fr]:
if H[fr] <= X:
return (-100, INF)
else:
return ((H[fr] - X + (H[to] - H[fr] - 1)) // (H[to] - H[fr]), INF)
else:
if H[fr] < X:
return (-100, (H[fr] - X) // (H[to] - H[fr]))
else:
return (0, -100)
while ans - ng > 1:
mid = (ans + ng) // 2
H[N] = mid
dist = [-1] * ((N + 1) * 2)
bfs = deque([N])
dist[N] = 0
while bfs:
vs = bfs.popleft()
v = vs % (N + 1)
c = vs // (N + 1)
for to0 in G[v]:
to = to0 + (1 - c) * (N + 1)
nl, nr = nminmax(v, to0, mid)
if nl <= dist[vs] <= nr and dist[to] == -1:
dist[to] = dist[vs] + 1
bfs.append(to)
mdist = dist[:]
for vs in range((N + 1) * 2):
if mdist[vs] == -1:
continue
if vs % (N + 1) == N:
continue
v = vs % (N + 1)
c = vs // (N + 1)
for to0 in G[v]:
to = to0 + (1 - c) * (N + 1)
nl, nr = nminmax(v, to0, mid)
if nr >= dist[vs] >= nl and H[to0] <= H[v]:
if c:
mdist[vs] = max(mdist[vs], nr - 1 + nr % 2 + 2)
mdist[to] = max(mdist[to], nr - 1 + nr % 2 + 1)
else:
mdist[vs] = max(mdist[vs], nr - nr % 2 + 2)
mdist[to] = max(mdist[to], nr - nr % 2 + 1)
mdist = [min(x, INF) if x >= 0 else x for x in mdist]
for h, v in Hord:
for c in range(2):
vs = v + c * (N + 1)
if mdist[vs] < 0:
continue
for to0 in G[v]:
to = to0 + (1 - c) * (N + 1)
nl, nr = nminmax(v, to0, mid)
if nl <= mdist[vs] <= nr:
mdist[to] = max(mdist[to], mdist[vs] + 1)
mdist[to] = min(mdist[to], INF)
ok = True
for i in range(N):
if mdist[i] == -1 and mdist[i + (N + 1)] == -1:
ok = False
if ok:
ans = mid
else:
ng = mid
print(ans)
# main
T = int(input())
for _ in range(T):
solve()