結果
問題 |
No.1283 Extra Fee
|
ユーザー |
![]() |
提出日時 | 2025-03-20 20:26:49 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,735 bytes |
コンパイル時間 | 189 ms |
コンパイル使用メモリ | 82,712 KB |
実行使用メモリ | 123,780 KB |
最終ジャッジ日時 | 2025-03-20 20:28:08 |
合計ジャッジ時間 | 6,033 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 11 TLE * 1 -- * 18 |
ソースコード
import heapq def main(): import sys input = sys.stdin.read().split() idx = 0 N = int(input[idx]) idx += 1 M = int(input[idx]) idx += 1 fees = {} for _ in range(M): h = int(input[idx]) idx += 1 w = int(input[idx]) idx += 1 c = int(input[idx]) idx += 1 fees[(h, w)] = c heap = [] heapq.heappush(heap, (0, 1, 1, 0, 0)) # (cost, h, w, state, max_fee) visited0 = {} # Key: (h, w), Value: {max_fee: minimal_cost} d1 = [[float('inf')] * (N + 2) for _ in range(N + 2)] # state 1's cost answer = float('inf') while heap: current_cost, h, w, state, current_max = heapq.heappop(heap) if h == N and w == N: answer = min(answer, current_cost) continue # Continue to find better paths if state == 0: if (h, w) not in visited0: visited0[(h, w)] = {} valid = True # Check if any existing entry with higher or equal max and lower or equal cost keys = list(visited0[(h, w)].keys()) for existing_max in keys: existing_cost = visited0[(h, w)][existing_max] if existing_max >= current_max and existing_cost <= current_cost: valid = False break if not valid: continue # Remove dominated entries (existing_max <= current_max and existing_cost >= current_cost) to_remove = [] for existing_max in keys: existing_cost = visited0[(h, w)][existing_max] if existing_max <= current_max and existing_cost >= current_cost: to_remove.append(existing_max) for k in to_remove: del visited0[(h, w)][k] # Add current entry if current_max in visited0[(h, w)]: if current_cost < visited0[(h, w)][current_max]: visited0[(h, w)][current_max] = current_cost else: visited0[(h, w)][current_max] = current_cost # Generate state 0 transitions for dh, dw in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nh = h + dh nw = w + dw if 1 <= nh <= N and 1 <= nw <= N: fee = fees.get((nh, nw), 0) new_cost0 = current_cost + 1 # Step cost if (nh, nw) in fees: new_cost0 += fee new_max = current_max if (nh, nw) in fees: new_max = max(new_max, fee) # Push state 0 transition heapq.heappush(heap, (new_cost0, nh, nw, 0, new_max)) # Generate state 1 transition (using skip) new_max_skip = new_max new_cost1 = current_cost + 1 if (nh, nw) in fees: new_cost1 += fee new_cost1 -= new_max_skip heapq.heappush(heap, (new_cost1, nh, nw, 1, 0)) else: # State 1: do not track max_fee anymore if current_cost >= d1[h][w]: continue d1[h][w] = current_cost for dh, dw in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nh = h + dh nw = w + dw if 1 <= nh <= N and 1 <= nw <= N: fee = fees.get((nh, nw), 0) new_cost1 = current_cost + 1 + fee if new_cost1 < d1[nh][nw]: d1[nh][nw] = new_cost1 heapq.heappush(heap, (new_cost1, nh, nw, 1, 0)) # Early exit if both queues have reached (N,N) # However, since heapq doesn't allow peeking, proceed until empty if answer != float('inf'): print(answer) else: # If all fees are skipped and path has none # Compute the normal BFS without fees from collections import deque visited = [[False]*(N+1) for _ in range(N+1)] q = deque([(1, 1, 0)]) visited[1][1] = True found = False while q: h, w, steps = q.popleft() if h == N and w == N: print(steps) found = True break for dh, dw in [(-1, 0), (1, 0), (0, -1), (0, 1)]: nh = h + dh nw = w + dw if 1 <= nh <= N and 1 <= nw <= N and not visited[nh][nw]: visited[nh][nw] = True q.append((nh, nw, steps+1)) if not found: print(-1) if __name__ == "__main__": main()