結果
問題 |
No.614 壊れたキャンパス
|
ユーザー |
![]() |
提出日時 | 2025-04-15 22:03:02 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 694 ms / 2,000 ms |
コード長 | 3,443 bytes |
コンパイル時間 | 172 ms |
コンパイル使用メモリ | 81,672 KB |
実行使用メモリ | 156,276 KB |
最終ジャッジ日時 | 2025-04-15 22:04:20 |
合計ジャッジ時間 | 6,079 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 20 |
ソースコード
import bisect from collections import defaultdict def main(): import sys input = sys.stdin.read data = input().split() idx = 0 n = int(data[idx]); idx +=1 m = int(data[idx]); idx +=1 k = int(data[idx]); idx +=1 s = int(data[idx]); idx +=1 t = int(data[idx]); idx +=1 bridges = [[] for _ in range(n+1)] # bridges[a] contains list of (b_i, c_i) for _ in range(m): a = int(data[idx]); idx +=1 b = int(data[idx]); idx +=1 c = int(data[idx]); idx +=1 bridges[a].append( (b, c) ) current = [ (s, 0) ] # list of (floor, cost) for current building for a in range(1, n): # Optimize current building's state current.sort() optimized = [] for f, c in current: if not optimized: optimized.append( (f, c) ) continue prev_f, prev_c = optimized[-1] if prev_c + (f - prev_f) <= c: continue # current point is dominated by previous # Check if previous points can be removed while optimized and (c + (f - prev_f) <= prev_c): optimized.pop() if optimized: prev_f, prev_c = optimized[-1] else: break optimized.append( (f, c) ) current = optimized if not current: break # no way to proceed # Process all bridges from building a to a+1 next_points = defaultdict(lambda: float('inf')) for b_i, c_i in bridges[a]: # Find the closest points in current to b_i idx_b = bisect.bisect_left(current, (b_i, -1)) candidates = [] if idx_b > 0: candidates.append(current[idx_b -1]) if idx_b < len(current): candidates.append(current[idx_b]) # Check for the minimal cost min_cost = float('inf') for (f, cost) in candidates: total = cost + abs(f - b_i) if total < min_cost: min_cost = total if min_cost < next_points[c_i]: next_points[c_i] = min_cost # Prepare next building's current state next_list = [] for c_i in next_points: next_list.append( (c_i, next_points[c_i]) ) # Optimize next_list next_list.sort() optimized_next = [] for f, c in next_list: if not optimized_next: optimized_next.append( (f, c) ) continue prev_f, prev_c = optimized_next[-1] if prev_c + (f - prev_f) <= c: continue # dominated by previous # Check if previous can be removed while optimized_next and (c + (f - prev_f) <= prev_c): optimized_next.pop() if optimized_next: prev_f, prev_c = optimized_next[-1] else: break optimized_next.append( (f, c) ) current = optimized_next if not current: print(-1) else: min_total = float('inf') for f, c in current: total = c + abs(f - t) if total < min_total: min_total = total print(min_total if min_total != float('inf') else -1) if __name__ == '__main__': main()