結果
| 問題 | No.614 壊れたキャンパス | 
| コンテスト | |
| ユーザー |  lam6er | 
| 提出日時 | 2025-04-15 22:02:26 | 
| 言語 | PyPy3 (7.3.15) | 
| 結果 | 
                                AC
                                 
                             | 
| 実行時間 | 507 ms / 2,000 ms | 
| コード長 | 2,879 bytes | 
| コンパイル時間 | 517 ms | 
| コンパイル使用メモリ | 81,956 KB | 
| 実行使用メモリ | 195,552 KB | 
| 最終ジャッジ日時 | 2025-04-15 22:03:44 | 
| 合計ジャッジ時間 | 6,068 ms | 
| ジャッジサーバーID (参考情報) | judge2 / judge3 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 20 | 
ソースコード
import bisect
def main():
    import sys
    input = sys.stdin.read().split()
    ptr = 0
    N = int(input[ptr])
    ptr +=1
    M = int(input[ptr])
    ptr +=1
    K = int(input[ptr])
    ptr +=1
    S = int(input[ptr])
    ptr +=1
    T = int(input[ptr])
    ptr +=1
    bridges = [[] for _ in range(N+1)]  # bridges[a] contains list of (b, c)
    for _ in range(M):
        a = int(input[ptr])
        ptr +=1
        b = int(input[ptr])
        ptr +=1
        c = int(input[ptr])
        ptr +=1
        bridges[a].append( (b, c) )
    # Initialize buildings. Each building has a dictionary of x: cost
    buildings = [dict() for _ in range(N+2)]  # 1-based
    buildings[1][S] = 0
    for i in range(1, N):
        if not bridges[i]:
            continue
        if not buildings[i]:
            continue
        # Process building i's bridges
        # Sort the x's in building i
        sorted_x = sorted(buildings[i].items(), key=lambda x: x[0])
        x_list = [x for x, cost in sorted_x]
        cost_list = [cost for x, cost in sorted_x]
        n = len(x_list)
        if n == 0:
            continue
        # Compute prefix minima (cost[x] - x)
        prefix_min = [0]*n
        prefix_min[0] = cost_list[0] - x_list[0]
        for j in range(1, n):
            prefix_min[j] = min(prefix_min[j-1], cost_list[j] - x_list[j])
        # Compute suffix minima (cost[x] + x)
        suffix_min = [0]*n
        suffix_min[-1] = cost_list[-1] + x_list[-1]
        for j in range(n-2, -1, -1):
            suffix_min[j] = min(suffix_min[j+1], cost_list[j] + x_list[j])
        # Process each bridge in building i
        for b, c in bridges[i]:
            # Find the minimal cost to reach b in building i
            # Binary search for the largest x <= b
            pos = bisect.bisect_right(x_list, b) -1
            min_left = float('inf')
            if pos >=0:
                min_left = prefix_min[pos] + b
            # Binary search for the smallest x >= b
            pos2 = bisect.bisect_left(x_list, b)
            min_right = float('inf')
            if pos2 < n:
                min_right = suffix_min[pos2] - b
            current_cost = min(min_left, min_right)
            if current_cost == float('inf'):
                continue
            # Update building i+1's c
            if c in buildings[i+1]:
                if current_cost < buildings[i+1][c]:
                    buildings[i+1][c] = current_cost
            else:
                buildings[i+1][c] = current_cost
    # Check building N
    if not buildings[N]:
        print(-1)
    else:
        min_total = float('inf')
        for x, cost in buildings[N].items():
            total = cost + abs(x - T)
            if total < min_total:
                min_total = total
        print(min_total if min_total != float('inf') else -1)
if __name__ == "__main__":
    main()
            
            
            
        