Problem:


Score : 500 points

Problem Statement

There are N cities numbered 1 to N, connected by M railroads.

You are now at City 1, with 10^{100} gold coins and S silver coins in your pocket.

The i-th railroad connects City U_i and City V_i bidirectionally, and a one-way trip costs A_i silver coins and takes B_i minutes.
You cannot use gold coins to pay the fare.

There is an exchange counter in each city. At the exchange counter in City i, you can get C_i silver coins for 1 gold coin.
The transaction takes D_i minutes for each gold coin you give.
You can exchange any number of gold coins at each exchange counter.

For each t=2, ..., N, find the minimum time needed to travel from City 1 to City t. You can ignore the time spent waiting for trains.

Constraints

2 \leq N \leq 50

N-1 \leq M \leq 100

0 \leq S \leq 10^9

1 \leq A_i \leq 50

1 \leq B_i,C_i,D_i \leq 10^9

1 \leq U_i < V_i \leq N

There is no pair i, j(i \neq j) such that (U_i,V_i)=(U_j,V_j).

Each city t=2,...,N can be reached from City 1 with some number of railroads.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M S
U_1 V_1 A_1 B_1
:
U_M V_M A_M B_M
C_1 D_1
:
C_N D_N

Output

For each t=2, ..., N in this order, print a line containing the minimum time needed to travel from City 1 to City t.

Sample Input 1

3 2 1
1 2 1 2
1 3 2 4
1 11
1 2
2 5

Sample Output 1

2
14

The railway network in this input is shown in the figure below.

In this figure, each city is labeled as follows:

The first line: the ID number i of the city (i for City i)

The second line: C_i / D_i

Similarly, each railroad is labeled as follows:

The first line: the ID number i of the railroad (i for the i-th railroad in input)

The second line: A_i / B_i

You can travel from City 1 to City 2 in 2 minutes, as follows:

Use the 1-st railroad to move from City 1 to City 2 in 2 minutes.

You can travel from City 1 to City 3 in 14 minutes, as follows:

Use the 1-st railroad to move from City 1 to City 2 in 2 minutes.

At the exchange counter in City 2, exchange 3 gold coins for 3 silver coins in 6 minutes.

Use the 1-st railroad to move from City 2 to City 1 in 2 minutes.

Use the 2-nd railroad to move from City 1 to City 3 in 4 minutes.

Sample Input 2

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

Sample Output 2

5
5
7

The railway network in this input is shown in the figure below:

You can travel from City 1 to City 4 in 7 minutes, as follows:

At the exchange counter in City 1, exchange 2 gold coins for 6 silver coins in 2 minutes.

Use the 2-nd railroad to move from City 1 to City 3 in 4 minutes.

Use the 4-th railroad to move from City 3 to City 4 in 1 minutes.

Sample Input 3

6 5 1
1 2 1 1
1 3 2 1
2 4 5 1
3 5 11 1
1 6 50 1
1 10000
1 3000
1 700
1 100
1 1
100 1

Sample Output 3

1
9003
14606
16510
16576

The railway network in this input is shown in the figure below:

You can travel from City 1 to City 6 in 16576 minutes, as follows:

Use the 1-st railroad to move from City 1 to City 2 in 1 minute.

At the exchange counter in City 2, exchange 3 gold coins for 3 silver coins in 9000 minutes.

Use the 1-st railroad to move from City 2 to City 1 in 1 minute.

Use the 2-nd railroad to move from City 1 to City 3 in 1 minute.

At the exchange counter in City 3, exchange 8 gold coins for 8 silver coins in 5600 minutes.

Use the 2-nd railroad to move from City 3 to City 1 in 1 minute.

Use the 1-st railroad to move from City 1 to City 2 in 1 minute.

Use the 3-rd railroad to move from City 2 to City 4 in 1 minute.

At the exchange counter in City 4, exchange 19 gold coins for 19 silver coins in 1900 minutes.

Use the 3-rd railroad to move from City 4 to City 2 in 1 minute.

Use the 1-st railroad to move from City 2 to City 1 in 1 minute.

Use the 2-nd railroad to move from City 1 to City 3 in 1 minute.

Use the 4-th railroad to move from City 3 to City 5 in 1 minute.

At the exchange counter in City 5, exchange 63 gold coins for 63 silver coins in 63 minutes.

Use the 4-th railroad to move from City 5 to City 3 in 1 minute.

Use the 2-nd railroad to move from City 3 to City 1 in 1 minute.

Use the 5-th railroad to move from City 1 to City 6 in 1 minute.

Sample Input 4

4 6 1000000000
1 2 50 1
1 3 50 5
1 4 50 7
2 3 50 2
2 4 50 4
3 4 50 3
10 2
4 4
5 5
7 7

Sample Output 4

1
3
5

The railway network in this input is shown in the figure below:

Sample Input 5

2 1 0
1 2 1 1
1 1000000000
1 1

Sample Output 5

1000000001

The railway network in this input is shown in the figure below:

You can travel from City 1 to City 2 in 1000000001 minutes, as follows:

At the exchange counter in City 1, exchange 1 gold coin for 1 silver coin in 1000000000 minutes.

Use the 1-st railroad to move from City 1 to City 2 in 1 minute.



Sample input:
3 2 1
1 2 1 2
1 3 2 4
1 11
1 2
2 5


Sample output:
2
14

Submission status: Accepted

Solution code:
from heapq import heappop, heappush

n,m,s = map(int,input().split())
e = [[] for _ in range(n)]
for i in range(m):
  u,v,a,b = map(int,input().split())
  u -= 1
  v -= 1
  e[u].append((v,a,b))
  e[v].append((u,a,b))
c = []
d = []
for i in range(n):
  x,y = map(int,input().split())
  c.append(x)
  d.append(y)

INF = float('inf')
def dijkstra(s,n,g): # sからの最短距離 頂点数n g[v]=[(u1,w1),(u2,w2)....]:vからuへの有向辺があり、重みw
  que = []
  d = [INF for _ in range(n)]
  d[s] = 0
  heappush(que,(0,s))
  while len(que) > 0:
    p = heappop(que)
    v = p[1]
    if d[v] < p[0]:
      continue
    for u,w in g[v]:
      if d[u] > d[v]+w:
        d[u] = d[v]+w
        heappush(que,(d[u],u))
  return d

def newv(v,s):
  return v*2500+s

s = min(s,2499)
e2 = [[] for _ in range(n*2500)]
for u in range(n):
  for j in range(2500):
    #if j+c[u] < 2500:
    #  e2[newv(u,j)].append((newv(u,j+c[u]),d[u]))
    e2[newv(u,j)].append((newv(u,min(j+c[u],2499)),d[u]))
    for v,a,b in e[u]:
      if j >= a:
        e2[newv(u,j)].append((newv(v,j-a),b))

l = dijkstra(newv(0,s),n*2500,e2)
for i in range(1,n):
  ans = INF
  for j in range(2500):
    ans = min(l[newv(i,j)],ans)
  print(ans)

Submission status: Accepted

Solution code:
# セイウチ

def main():
    from heapq import heappush, heappop

    INF = 1 << 60
    MX_AG = 2500

    N, M, S = map(int, input().split())
    S = min(S, MX_AG)  # それ以上のAgは不要

    g = tuple(set() for _ in range(N))
    for _ in range(M):
        u, v, a, b = map(int, input().split())
        u -= 1
        v -= 1
        g[u].add((v, a, b))
        g[v].add((u, a, b))

    exchange = []
    for _ in range(N):
        c, d = map(int, input().split())
        exchange.append((c, d))

    h = [(0, S, 0)]

    time = [[INF] * (MX_AG + 1) for _ in range(N)]
    time[0][S] = 0
    # time[location][r_Ag]:=minimum_time_to_reach

    while h:
        t, ag, loc = heappop(h)
        for to, fare, dt in g[loc]:
            if (n_Ag := ag - fare) < 0: continue
            if time[to][n_Ag] <= (n_time := t + dt): continue
            time[to][n_Ag] = n_time
            heappush(h, (n_time, n_Ag, to))

        if (e_Ag := ag + exchange[loc][0]) > MX_AG: continue
        if time[loc][e_Ag] <= (e_time := t + exchange[loc][1]): continue
        time[loc][e_Ag] = e_time
        heappush(h, (e_time, e_Ag, loc))

    ans = (min(time[to]) for to in range(1, N))

    print(*ans, sep='\n')


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
    from heapq import heappush, heappop

    INF = 1 << 60
    MX_AG = 2500

    N, M, S = map(int, input().split())
    S = min(S, MX_AG)  # それ以上のAgは不要

    g = tuple(set() for _ in range(N))
    for _ in range(M):
        u, v, a, b = map(int, input().split())
        u -= 1
        v -= 1
        g[u].add((v, a, b))
        g[v].add((u, a, b))

    exchange = []
    for _ in range(N):
        c, d = map(int, input().split())
        exchange.append((c, d))

    h = [(0, S, 0)]

    time = [[INF] * (MX_AG + 1) for _ in range(N)]
    time[0][S] = 0
    # time[location][r_Ag]:=minimum_time_to_reach

    while h:
        t, ag, loc = heappop(h)
        for to, fare, dt in g[loc]:
            n_Ag = ag - fare
            if n_Ag < 0: continue
            cf = time[to][n_Ag]
            n_time = t + dt
            if cf <= n_time: continue
            time[to][n_Ag] = n_time
            heappush(h, (n_time, n_Ag, to))

        e_time = t + exchange[loc][1]
        e_Ag = ag + exchange[loc][0]
        if e_Ag > MX_AG: continue
        cf = time[loc][e_Ag]
        if cf <= e_time: continue
        time[loc][e_Ag] = e_time
        heappush(h, (e_time, e_Ag, loc))

    ans = (min(time[to]) for to in range(1, N))

    print('\n'.join(map(str, ans)))


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
    from heapq import heappush, heappop

    INF = 1 << 60
    MX_AG = 2500

    N, M, S = map(int, input().split())
    S = min(S, MX_AG)  # それ以上のAgは不要

    g = tuple(set() for _ in range(N))
    for _ in range(M):
        u, v, a, b = map(int, input().split())
        u -= 1
        v -= 1
        g[u].add((v, a, b))
        g[v].add((u, a, b))

    exchange = []
    for _ in range(N):
        c, d = map(int, input().split())
        exchange.append((c, d))

    h = [(0, S, 0)]

    time = [[INF] * (MX_AG + 1) for _ in range(N)]
    time[0][S] = 0
    # time[location][r_Ag]:=minimum_time_to_reach

    while h:
        t, ag, loc = heappop(h)
        for to, fare, dt in g[loc]:
            n_Ag = ag - fare
            if n_Ag < 0: continue
            cf = time[to][n_Ag]
            n_time = t + dt
            if cf <= n_time: continue
            time[to][n_Ag] = n_time
            heappush(h, (n_time, n_Ag, to))

        e_time = t + exchange[loc][1]
        e_Ag = ag + exchange[loc][0]
        if e_Ag > MX_AG: continue
        cf = time[loc][e_Ag]
        if cf <= e_time: continue
        time[loc][e_Ag] = e_time
        heappush(h, (e_time, e_Ag, loc))

    ans = (min(time[to]) for to in range(1, N))

    print(*ans, sep='\n')


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
    from heapq import heappush, heappop

    INF = 1 << 60
    MX_AG = 2500

    N, M, S = map(int, input().split())
    S = min(S, MX_AG)  # それ以上のAgは不要

    g = tuple(set() for _ in range(N))
    for _ in range(M):
        u, v, a, b = map(int, input().split())
        u -= 1
        v -= 1
        g[u].add((v, a, b))
        g[v].add((u, a, b))

    exchange = []
    for _ in range(N):
        c, d = map(int, input().split())
        exchange.append((c, d))

    h = [(0, S, 0)]

    time = [[INF] * (MX_AG + 1) for _ in range(N)]
    time[0][S] = 0
    # time[location][r_Ag]:=minimum_time_to_reach

    while h:
        t, ag, loc = heappop(h)
        for to, fare, dt in g[loc]:
            n_Ag = ag - fare
            if n_Ag < 0: continue
            cf = time[to][n_Ag]
            n_time = t + dt
            if cf <= n_time: continue
            time[to][n_Ag] = n_time
            heappush(h, (n_time, n_Ag, to))

        e_time = t + exchange[loc][1]
        e_Ag = ag + exchange[loc][0]
        if e_Ag > MX_AG: continue
        cf = time[loc][e_Ag]
        if cf <= e_time: continue
        time[loc][e_Ag] = e_time
        heappush(h, (e_time, e_Ag, loc))

    for to in range(1, N):
        print(min(time[to]))


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def main():
    import dataclasses
    from heapq import heappush, heappop

    @dataclasses.dataclass(frozen=True)
    class Path:
        to: int
        fare: int
        travel_time: int

    @dataclasses.dataclass(frozen=True)
    class ExchangeRate:
        Ag: int
        exchange_time: int

    @dataclasses.dataclass(frozen=True)
    class Traveler:
        consumption_time: int
        remaining_Ag: int
        location: int

        def __gt__(self, other):
            return self.consumption_time > other.consumption_time

        def __eq__(self, other):
            return self.consumption_time == other.consumption_time

    INF = 1 << 60
    MX_AG = 2500

    N, M, S = map(int, input().split())
    S = min(S, MX_AG)  # それ以上のAgは不要

    g = tuple(set() for _ in range(N))
    for _ in range(M):
        u, v, a, b = map(int, input().split())
        u -= 1
        v -= 1
        g[u].add(Path(v, a, b))
        g[v].add(Path(u, a, b))

    exchange = []
    for _ in range(N):
        c, d = map(int, input().split())
        exchange.append(ExchangeRate(c, d))

    h = [Traveler(0, S, 0)]

    time = [[INF] * (MX_AG + 1) for _ in range(N)]
    time[0][S] = 0
    # time[location][r_Ag]:=minimum_time_to_reach

    while h:
        t = heappop(h)
        for p in g[t.location]:
            n_Ag = t.remaining_Ag - p.fare
            if n_Ag < 0: continue
            cf = time[p.to][n_Ag]
            n_time = t.consumption_time + p.travel_time
            if cf <= n_time: continue
            time[p.to][n_Ag] = n_time
            heappush(h, Traveler(consumption_time=n_time, remaining_Ag=n_Ag, location=p.to))

        e_time = t.consumption_time + exchange[t.location].exchange_time
        e_Ag = t.remaining_Ag + exchange[t.location].Ag
        if e_Ag > MX_AG: continue
        cf = time[t.location][e_Ag]
        if cf <= e_time: continue
        time[t.location][e_Ag] = e_time
        heappush(h, Traveler(consumption_time=e_time, remaining_Ag=e_Ag, location=t.location))

    for to in range(1, N):
        print(min(time[to]))


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
def e_two_currencies(INF = float('inf')):
    # 参考: https://atcoder.jp/contests/abc164/submissions/12429145
    import heapq
    N, M, S = map(int, input().split())

    Edges = [[] for _ in range(N)]
    max_a = 0
    for _ in range(M):
        u, v, a, b = [int(i) for i in input().split()]
        Edges[u - 1].append((v - 1, a, b))
        Edges[v - 1].append((u - 1, a, b))
        max_a = max(max_a, a)

    Exchanges = []
    Times = []
    for n in range(N):
        c, d = [int(i) for i in input().split()]
        Exchanges.append(c)
        Times.append(d)

    max_coin = max_a * N
    initial_silver = min(S, max_coin)  # 制約上、これ以上持っていても同じこと

    # dist[i][j]: 都市 i へ銀貨の枚数 j で向かうための最短時間
    dist = [[INF] * (max_coin + 1) for _ in range(N)]
    dist[0][initial_silver] = 0
    # (所要時間, 手持ちの銀貨の枚数, 都市番号) heap で扱いやすいようにこの順にする
    queue = [(0, initial_silver, 0)]

    while queue:
        time, silver, city = heapq.heappop(queue)
        if dist[city][silver] < time:  # これまでの最短時間より長い。探索不要
            continue

        # 都市 city で銀貨に交換することを考える。交換しても銀貨が必要最大量に届かず、
        # 移動して銀貨に交換する時間がこれまでの最短時間より短い場合、移動を検討する
        # 同じ頂点 (city, silver) に複数回行く意味はないので、更新は 1 回分のみ
        if (silver + Exchanges[city] < max_coin
                and time + Times[city] < dist[city][silver + Exchanges[city]]):
            dist[city][silver + Exchanges[city]] = time + Times[city]
            heapq.heappush(queue, (time + Times[city], silver + Exchanges[city], city))

        # 都市 city から鉄道で移動する。
        for next_city, a, b in Edges[city]:
            # 運賃以上の銀貨を持っており、移動すると最短時間を更新できる
            if silver >= a and time + b < dist[next_city][silver - a]:
                dist[next_city][silver - a] = time + b
                heapq.heappush(queue, (time + b, silver - a, next_city))

    # 都市 1→1 は省く (明らかに 0 分)。また、残った銀貨の枚数は関係ない
    ans = [min(d) for d in dist[1:]]
    return ' '.join(map(str, ans))

print(e_two_currencies())

Submission status: Accepted

Solution code:
import heapq


dp = {}
hq = []

N, M, S = map(int, input().split())

MAX_S = (N-1)*50
INF = 10**18
S = min(S, MAX_S)

for i in range(1,N+1):
    dp[i] = {}
    for j in range(MAX_S+1):
        dp[i][j] = INF

uv = {}
for i in range(N):
    uv[i+1] = []
for i in range(M):
    U, V, A, B = map(int, input().split())
    uv[U].append((V,A,B))
    uv[V].append((U,A,B))

c = {}
d = {}
for i in range(N):
    C, D = map(int, input().split())
    c[i+1] = C
    d[i+1] = D

def q_push(v, money, time):
    if money < 0:
        return 
    if dp[v][money] <= time:
        return
    dp[v][money] = time
    heapq.heappush(hq, (time, v, money))


q_push(1,S,0)
while hq:
    now_t, now_v, now_m = heapq.heappop(hq)

    if dp[now_v][now_m] != now_t:
        continue

    new_money = min(now_m+c[now_v],MAX_S)
    q_push(now_v,new_money,now_t+d[now_v])
    for next_v, next_a, next_b in uv[now_v]:
        q_push(next_v,now_m-next_a,now_t+next_b)

for i in range(2, N+1):
    ans = INF
    for j in range(0, MAX_S+1):
        ans = min(ans, dp[i][j])
    
    print(ans)

Submission status: Accepted

Solution code:
import heapq
def dijkstra_heap():
    used = [-1] * (2451*n)
    edgelist=[]
    heapq.heappush(edgelist,[0,ss])
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        if used[minedge[1]]!=-1:
            continue
        v = minedge[1]
        kai=minedge[0]
        mai=v%2451
        used[v] = kai
        for e in edge[v//2451]:
            if mai-e[1]>=0:
                sss=mai-e[1]
                if used[e[2]*2451+sss]==-1:
                    heapq.heappush(edgelist,[e[0]+kai,e[2]*2451+sss])
        if mai+cd[v//2451][0]<=2450:
            if used[v+cd[v//2451][0]]==-1:
                heapq.heappush(edgelist,[kai+cd[v//2451][1],v+cd[v//2451][0]])
    return used

################################
n,m,ss = map(int,input().split())
ss=min(2450,ss)
edge = [[] for i in range(n)]

for i in range(m):
    x,y,a,b = map(int,input().split())
    edge[x-1].append([b,a,y-1])
    edge[y-1].append([b,a,x-1])
cd=[]
for i in range(n):
    cd.append(list(map(int,input().split())))
pp=dijkstra_heap()
for i in range(1,n):
    ans=10**20
    for j in range(2451):
        if pp[i*2451+j]!=-1:
            ans=min(ans,pp[i*2451+j])
    print(ans)

Submission status: Accepted

Solution code:
import heapq
def dijkstra_heap():
    used = [-1] * (2451*n)
    edgelist=[]
    heapq.heappush(edgelist,[0,ss])
    while len(edgelist):
        #print(len(edgelist))
        minedge = heapq.heappop(edgelist)
        if used[minedge[1]]!=-1:
            continue
        v = minedge[1]
        kai=minedge[0]
        mai=v%2451
        used[v] = kai
        for e in edge[v//2451]:
            if mai-e[1]>=0:
                sss=mai-e[1]
                if used[e[2]*2451+sss]==-1:
                    heapq.heappush(edgelist,[e[0]+kai,e[2]*2451+sss])
        if mai+cd[v//2451][0]<=2450:
            if used[v+cd[v//2451][0]]==-1:
                heapq.heappush(edgelist,[kai+cd[v//2451][1],v+cd[v//2451][0]])
    return used

################################
n,m,ss = map(int,input().split())
ss=min(2450,ss)
edge = [[] for i in range(n)]

for i in range(m):
    x,y,a,b = map(int,input().split())
    edge[x-1].append([b,a,y-1])
    edge[y-1].append([b,a,x-1])
cd=[]
for i in range(n):
    cd.append(list(map(int,input().split())))
pp=dijkstra_heap()
for i in range(1,n):
    ans=10**20
    for j in range(2451):
        if pp[i*2451+j]!=-1:
            ans=min(ans,pp[i*2451+j])
    print(ans)

Submission status: Accepted

Solution code:
def solve():
    import sys
    input = sys.stdin.readline
    N,M,S = map(int,input().split())
    UVAB = [tuple(map(int,input().split())) for i in range(M)]
    CD = [tuple(map(int,input().split())) for i in range(N)]

    es = [[] for _ in range(N)]
    for u,v,a,b in UVAB:
        u,v = u-1,v-1
        es[u].append((v,a,b))
        es[v].append((u,a,b))

    INF = float('inf')
    times = [INF] * (2501 * N)
    start = min(2500,S)*N
    times[start] = 0
    hq = [start]
    ans = [-1] * N
    ans[0] = 0
    reached = 0
    import heapq
    heapq.heapify(hq)
    while hq:
        x = heapq.heappop(hq)
        t,v = divmod(x,N*2501)
        s,i = divmod(v,N)
        if ans[i] < 0:
            ans[i] = t
            reached += 1
            if reached == N-1: break
        for to,a,b in es[i]:
            if a > s: continue
            nv = (s-a)*N + to
            if times[nv] <= t + b: continue
            times[nv] = t + b
            heapq.heappush(hq, (t+b)*N*2501 + nv)
        ns = s
        nt = times[v]
        while ns <= 2500:
            ns += CD[i][0]
            nt += CD[i][1]
            nv = min(2500,ns)*N + i
            if times[nv] <= nt: break
            times[nv] = nt
            heapq.heappush(hq, nt*N*2501 + nv)
    print(*ans[1:], sep='\n')
solve()

Submission status: Accepted

Solution code:
from heapq import *
N, M, S = map(int, input().split())
graph = [[] for _ in range(N)]
amax = 0
for i in range(M):
  u, v, a, b = map(int, input().split())
  u -= 1
  v -= 1
  graph[u].append([v, a, b])
  graph[v].append([u, a, b])
  amax = max(amax, a)
  
lcoins = amax * (N-1)
  
cost = list()
time = list()
for _ in range(N):
  c, d = map(int, input().split())
  cost.append(c)
  time.append(d)

INF = float('INF')
M = 2500
if(S >= M):
  S = M-1

dist = [[INF] * M for _ in range(N)]
dist[0][S] = 0
q = [(0, S, 0)]

while q:
  dv, num, v = heappop(q)
  
  if dist[v][num] < dv:
    continue
    
  if num + cost[v] < M and dv + time[v] < dist[v][num+cost[v]]:
    dist[v][num+cost[v]] = dv + time[v]
    heappush(q, (dv+time[v], num+cost[v], v))
    
  for next, a, b in graph[v]:
    if num >= a and dv+b < dist[next][num-a]:
      dist[next][num-a] = dv+b
      heappush(q, (dv+b, num-a, next))
      
for i in range(1,N):
  print(min(dist[i]))

Submission status: Accepted

Solution code:
import sys,math,copy,queue,itertools,bisect,collections
from heapq import *
LI = lambda : [int(x) for x in sys.stdin.readline().split()]
INF = 10**15

N,M,S = LI()
if S > N * 50:
    S = N * 50
root = [[] for _ in range(N)]
for _ in range(M):
    u,v,a,b = LI()
    root[u-1].append((v-1,a,b))
    root[v-1].append((u-1,a,b))
city = [LI() for _ in range(N)]

dp = [[INF] * (N*50+1) for _ in range(N)]
dp[0][S] = 0

hq = [[0,0,S]]
heapify(hq)

while hq:
    tm,pos,coin = heappop(hq)

    c = coin
    t = tm
    if c < N * 50:
        c += city[pos][0]
        c = min(c, N * 50)
        t += city[pos][1]
        if dp[pos][c] > t:
            dp[pos][c] = t
            heappush(hq,[t,pos,c])

    for p,a,b in root[pos]:
        c = coin - a
        if c >= 0:
            if dp[p][c] > tm + b:
                dp[p][c] = tm + b
                heappush(hq,[tm+b,p,c])

for i in range(1,N):
    print(min(dp[i]))

Submission status: Accepted

Solution code:
import heapq
N, M, init_silver = map(int, input().split())
MAX_COST = 2500
init_silver = min(init_silver, MAX_COST)

G = [[] for _ in range(N)]
for i in range(M):
    u, v, silver_cost, time_cost = map(int, input().split())
    u, v = u - 1, v - 1
    G[u].append([v, silver_cost, time_cost])
    G[v].append([u, silver_cost, time_cost])

change_rate, change_cost = [], []
for i in range(N):
    rate, cost = map(int, input().split())
    G[i].append([i, -rate, cost])
    change_rate.append(rate)
    change_cost.append(cost)


# dp[i][silver] := 頂点iにいて銀貨をsilver枚持っているような状況を作るために必要な最小時間
dp = [[float('inf')] * (MAX_COST + 1) for _ in range(N)]
dp[0][init_silver] = 0

# 優先度付きキュー: (time, node, silver)
hq = [(0, 0, init_silver)]
while hq:
    time, node, silver = heapq.heappop(hq)

    # self_loop_silver = min(silver + change_rate[node], MAX_COST)
    # self_loop_cost = time + change_cost[node]
    # if self_loop_cost < dp[node][self_loop_silver]:
    #     dp[node][self_loop_silver] = self_loop_cost
    #     heapq.heappush(hq, (time + change_cost[node], node, self_loop_silver))

    for to, silver_cost, time_cost in G[node]:
        remain_silver = min(silver - silver_cost, MAX_COST)
        if remain_silver < 0:
            continue

        dp_next_value = time + time_cost
        if dp[to][remain_silver] <= dp_next_value:
            continue

        dp[to][remain_silver] = dp_next_value
        heapq.heappush(hq, (dp_next_value, to, remain_silver))

print(*[min(d) for d in dp[1:]], sep="\n")

Submission status: Accepted

Solution code:
import heapq
N, M, init_silver = map(int, input().split())
MAX_COST = 2500
init_silver = min(init_silver, MAX_COST)

G = [[] for _ in range(N)]
for i in range(M):
    u, v, silver_cost, time_cost = map(int, input().split())
    u, v = u - 1, v - 1
    G[u].append([v, silver_cost, time_cost])
    G[v].append([u, silver_cost, time_cost])

change_rate, change_cost = [], []
for i in range(N):
    rate, cost = map(int, input().split())
    change_rate.append(rate)
    change_cost.append(cost)


# dp[i][silver] := 頂点iにいて銀貨をsilver枚持っているような状況を作るために必要な最小時間
dp = [[float('inf')] * (MAX_COST + 1) for _ in range(N)]
dp[0][init_silver] = 0

# 優先度付きキュー: (time, node, silver)
hq = [(0, 0, init_silver)]
while hq:
    time, node, silver = heapq.heappop(hq)

    self_loop_silver = min(silver + change_rate[node], MAX_COST)
    self_loop_cost = time + change_cost[node]
    if self_loop_cost < dp[node][self_loop_silver]:
        dp[node][self_loop_silver] = self_loop_cost
        heapq.heappush(hq, (time + change_cost[node], node, self_loop_silver))

    for to, silver_cost, time_cost in G[node]:
        remain_silver = min(silver - silver_cost, MAX_COST)
        if remain_silver < 0:
            continue

        dp_next_value = time + time_cost
        if dp[to][remain_silver] <= dp_next_value:
            continue

        dp[to][remain_silver] = dp_next_value
        heapq.heappush(hq, (dp_next_value, to, remain_silver))

print(*[min(d) for d in dp[1:]], sep="\n")

Submission status: Accepted

Solution code:
import math
import heapq

N,M,S=map(int,input().split())

Us=[0]*M
Vs=[0]*M
As=[0]*M
Bs=[0]*M
for i in range(M):
    Us[i],Vs[i],As[i],Bs[i] = map(int,input().split())
    Us[i] -= 1
    Vs[i] -= 1

# ---
V={}
Ns = max(As)*N
Nv=N*(Ns+1)
cnt=0
for i in range(N):
    for ns in range(Ns+1):
        V[(i,ns)]=cnt
        cnt+=1

G=[[] for _ in range(Nv)]

if S > Ns:
    S = Ns

# U <-> V
for _ in range(M):
    u = Us.pop()
    v = Vs.pop()
    a = As.pop()
    b = Bs.pop()
    #
    for i in range(Ns+1): # i = 0,..,Ns
        ns_s = Ns - i
        ns_g = ns_s - a
        if ns_g >= 0:
            # U -> V
            G[ V[(u,ns_s)] ].append( (V[(v,ns_g)],b) )
            # V -> U
            G[ V[(v,ns_s)] ].append( (V[(u,ns_g)],b) )
            #print(u,v,a,b,ns_s,ns_g,V[(u,ns_s)],V[(v,ns_g)])

# -----

for i in range(N):
    c,d = map(int,input().split())
    for j in range(Ns): # j = 0,...,Ns-1
        ns_s = j
        ns_g = j + c
        if ns_g > Ns:
            ns_g = Ns
        G[ V[(i,ns_s)] ].append( (V[(i,ns_g)],d) )

# -----
D=[math.inf]*Nv
q=[]
# -----

s=V[(0,S)]
D[s] = 0
heapq.heappush(q,(0,s))

while len(q) > 0:
    p_cost,p_v = heapq.heappop(q)
    if D[p_v] < p_cost:
        continue
    for e_to,e_cost in G[p_v]:
        if D[ e_to ] > D[p_v] + e_cost:
            D[e_to] = D[p_v] + e_cost
            heapq.heappush(q, (D[e_to], e_to))

for i in range(1,N):
    ans = min([D[i*(Ns+1)+v] for v in range(Ns+1)])
    print(ans)

Submission status: Accepted

Solution code:
import heapq

N, M, S = map(int, input().split(" "))
# (city i, silver: S) -> S * N + i
edges = {i: [] for i in range(2501 * N - 1)}

for i in range(M):
    U, V, A, B = map(int, input().split(" "))
    edges[U - 1].append((V - 1, A, B))
    edges[V - 1].append((U - 1, A, B))

exchange_edges = {}
for i in range(N):
    C, D = map(int, input().split(" "))
    exchange_edges[i] = (C, D)

dist = [[-1 for _ in range(2501)] for _ in range(N)]
que = []
heapq.heappush(que, (0, 0, min(S, 2500)))

while que:
    time, now, s = heapq.heappop(que)
    if dist[now][s] != -1:
        continue
    dist[now][s] = time
    # normal edge
    for (to, a, b) in edges[now]:
        if a > s or dist[to][s - a] != -1:
            continue
        heapq.heappush(que, (time + b, to, s - a))

    # exchange_edge
    (silv, t) = exchange_edges[now]
    if s + silv <= 2500 and dist[now][silv + s] == -1:
        heapq.heappush(que, (time + t, now, s + silv))

for i in range(1, N):
    print(min(dist[i]))

Submission status: Accepted

Solution code:
from heapq import *

n, m, s = map(int, input().split())
s = min([s, 50*n])
tree = [[] for _i in range(n+1)]
for _i in range(m):
    u, v, a, b = map(int, input().split())
    tree[u].append([v, a, b])
    tree[v].append([u, a, b])

cd = [[0,0]]
for _i in range(n):
    cd.append(list(map(int, input().split())))

dp = [[float('inf') for _i in range(50*n+1)] for _j in range(n+1)]
hq = [[0, 1, s]]
dp[1][s] = 0
heapify(hq)
while hq:
    t, p, g = heappop(hq)
    if g+cd[p][0] <= 50*n:
        x, y = t+cd[p][1], min([g+cd[p][0], 50*n])
        if dp[p][y] > x:
            dp[p][y] = x
            heappush(hq, [x, p, y])
    for x, y, z in tree[p]:
        if g-y >= 0 and dp[x][g-y] > t+z:
            dp[x][g-y] = t+z
            heappush(hq, [t+z, x, g-y])

for i in dp[2:]:
    print(min(i))

Submission status: Accepted

Solution code:
# ABC 164 E 草案
import sys
sys.setrecursionlimit(10**6)

n,m,s= map(int, input().split())
g= [list(map(int, input().split())) for i in range(m)]
# 両替所
c= [list(map(int, input().split())) for i in range(n)]

x=2501
# 作るグラフ (点,所有銀貨,必要時間)
gg=[[[] for i in range(x)] for i in range(n)]
for i in range(n):
    for j in range(x-1):
        # 金貨を銀貨に交換
        y=j+c[i][0]
        if y>=x-1:
            y=x-1
        gg[i][j].append((i,y,c[i][1]))


for i in range(1,x):
    for u,v,a,b in g:
        u-=1
        v-=1
        # 銀貨足りる時移動できる
        if i-a>=0:
            gg[v][i].append((u,i-a,b))
            gg[u][i].append((v,i-a,b))





#ダイクストラ法
from heapq import heappush, heappop

def dijkstra(edges, size, source,gold):
    # edge=探索するグラフ
    # size=グラフの点の数
    # source=スタート点
    distance = [[float('inf')]*x for i in range(n)]
    distance[source][gold] = 0
    visited = [[False]*x for i in range(n)]
    pq = []
    heappush(pq, (0, source,gold))
    while pq:
        dist_v, u,v = heappop(pq)
        visited[u][v] = True
        for u,v, weight in edges[u][v]:
            if not visited[u][v]:
                new_dist = dist_v + weight
                if distance[u][v] > new_dist:
                    distance[u][v] = new_dist
                    heappush(pq, (new_dist, u,v))
    return distance
s=min(2500,s)
ans=dijkstra(gg,n,0,s)

for i in range(1,n):
    print(min(ans[i]))

Submission status: Accepted

Solution code:
# ABC 164 E 草案
import sys
sys.setrecursionlimit(10**6)

n,m,s= map(int, input().split())
g= [list(map(int, input().split())) for i in range(m)]
# 両替所
c= [list(map(int, input().split())) for i in range(n)]

x=2501
# 作るグラフ (点,所有銀貨,必要時間)
gg=[[[] for i in range(x)] for i in range(n)]
for i in range(n):
    for j in range(x-1):
        # 金貨を銀貨に交換
        y=j+c[i][0]
        if y>=x-1:
            y=x-1
        gg[i][j].append((i,y,c[i][1]))


for i in range(1,x):
    for u,v,a,b in g:
        u-=1
        v-=1
        # 銀貨足りる時移動できる
        if i-a>=0:
            gg[v][i].append((u,i-a,b))
            gg[u][i].append((v,i-a,b))





#ダイクストラ法
from heapq import heappush, heappop

def dijkstra(edges, size, source,gold):
    # edge=探索するグラフ
    # size=グラフの点の数
    # source=スタート点
    distance = [[float('inf')  for i in range(x)] for i in range(n)]
    distance[source][gold] = 0
    visited = [[False  for i in range(x)] for i in range(n)]
    pq = []
    heappush(pq, (0, source,gold))
    while pq:
        dist_v, u,v = heappop(pq)
        visited[u][v] = True
        for u,v, weight in edges[u][v]:
            if not visited[u][v]:
                new_dist = dist_v + weight
                if distance[u][v] > new_dist:
                    distance[u][v] = new_dist
                    heappush(pq, (new_dist, u,v))
    return distance
s=min(2500,s)
ans=dijkstra(gg,n,0,s)

for i in range(1,n):
    print(min(ans[i]))