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: Time Limit Exceeded

Solution code:
import sys
from heapq import heappop, heappush

n, m, ss = map(int, input().split())
lines = sys.stdin.readlines()
links = [set() for _ in range(n)]
aaa = []
for line in lines[:m]:
    u, v, a, b = map(int, line.split())
    u -= 1
    v -= 1
    links[u].add((v, a, b))
    links[v].add((u, a, b))
    aaa.append(a)

exchanges = []
for line in lines[m:]:
    c, d = map(int, line.split())
    exchanges.append((c, d))

req = sum(sorted(aaa, reverse=True)[:n])
INF = 10 ** 18
ans = [INF] * n

q = [(0, ss, 0, 0)]  # (time, silver, city, type)
visited = set()
fixed = 0
while q:
    t, s, v, z = heappop(q)
    if (s, v) in visited:
        continue
    visited.add((s, v))
    if ans[v] == INF:
        ans[v] = t
        fixed += 1
        if fixed == n:
            break

    for u, a, b in links[v]:
        if s < a:
            continue
        ns = s - a
        if (ns, u) in visited:
            continue
        heappush(q, (t + b, ns, u, 0))

    if z == 1:
        continue

    ts = s
    tt = t
    c, d = exchanges[v]
    while ts <= req:
        ts += c
        tt += d
        if (ts, v) in visited:
            break
        heappush(q, (tt, ts, v, 1))

print('\n'.join(map(str, ans[1:])))

Submission status: Time Limit Exceeded

Solution code:
from heapq import heappush, heappop
import sys
input = sys.stdin.readline

def dijkstra(edges, size, source):
    distance = [float('inf')] * size
    distance[source] = 0
    visited = [False] * size
    pq = []
    heappush(pq, (0, source))
    while pq:
        dist_v, v = heappop(pq)
        visited[v] = True
        for u, weight in edges[v]:
            if not visited[u]:
                new_dist = dist_v + weight
                if distance[u] > new_dist:
                    distance[u] = new_dist
                    heappush(pq, (new_dist, u))
    return distance

N, M, S = map(int, input().split())
MAX = 10000
AB = [[None] * N for _ in range(N)]
for _ in range(M):
    U, V, A, B = map(int, input().split())
    U -= 1
    V -= 1
    AB[U][V] = AB[V][U] = (A, B)
CD = [tuple(map(int, input().split())) for _ in range(N)]
edges = [[] for _ in range(N*(MAX+1))]
for v in range(N):
    C, D = CD[v]
    for i in range(MAX):
        edges[v*(MAX+1)+i].append((min(v*(MAX+1)+i+C, (v+1)*(MAX+1)-1), D))
for u in range(N-1):
    for v in range(u+1, N):
        if not AB[u][v]:
            continue
        A, B = AB[u][v]
        for i in range(A, MAX+1):
            edges[u*(MAX+1)+i].append((v*(MAX+1)+i-A, B))
            edges[v*(MAX+1)+i].append((u*(MAX+1)+i-A, B))
dist = dijkstra(edges, N*(MAX+1), min(S, MAX))
for v in range(1, N):
    print(min(dist[v*(MAX+1):(v+1)*(MAX+1)]))

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline

N,M,S=map(int,input().split())
E=[[] for i in range(N+1)]
for i in range(M):
    u,v,a,b=map(int,input().split())
    E[u].append((v,a,b))
    E[v].append((u,a,b))

C=[(0,0)]+[tuple(map(int,input().split())) for i in range(N)]
DP=[[1<<64]*5001 for i in range(51)]

import heapq

Q=[(0,min(S,5000),1)]
DP[1][min(S,5000)]=0

while Q:
    time,money,town = heapq.heappop(Q)

    for to,pmoney,ptime in E[town]:
        if money>=pmoney and DP[to][money-pmoney]>time+ptime:
            DP[to][money-pmoney]=time+ptime
            heapq.heappush(Q,(time+ptime,money-pmoney,to))
            
    if DP[town][min(money+C[town][0],5000)]>time+C[town][1]:
        DP[town][min(money+C[town][0],5000)]=time+C[town][1]
        heapq.heappush(Q,(time+C[town][1],min(money+C[town][0],5000),town))
        
for i in range(2,N+1):
    print(min(DP[i]))

Submission status: Time Limit Exceeded

Solution code:
import sys
from heapq import heappop, heappush

n, m, ss, *uvabcd = map(int, sys.stdin.buffer.read().split())
uuu = uvabcd[0:4 * m:4]
vvv = uvabcd[1:4 * m:4]
aaa = uvabcd[2:4 * m:4]
bbb = uvabcd[3:4 * m:4]
ccc = uvabcd[4 * m + 0::2]
ddd = uvabcd[4 * m + 1::2]
links = [set() for _ in range(n)]

for u, v, a, b in zip(uuu, vvv, aaa, bbb):
    u -= 1
    v -= 1
    links[u].add((v, a, b))
    links[v].add((u, a, b))

req = sum(sorted(aaa, reverse=True)[:n])
INF = 10 ** 18
ans = [INF] * n

q = [(0, ss, 0, 0)]  # (time, silver, city, type)
visited = set()
fixed = 0
while q:
    t, s, v, z = heappop(q)
    if (s, v) in visited:
        continue
    visited.add((s, v))
    if ans[v] == INF:
        ans[v] = t
        fixed += 1
        if fixed == n:
            break

    for u, a, b in links[v]:
        if s < a:
            continue
        ns = s - a
        if (ns, u) in visited:
            continue
        heappush(q, (t + b, ns, u, 0))

    if z == 1:
        continue

    ts = s
    tt = t
    c = ccc[v]
    d = ddd[v]
    while ts <= req:
        ts += c
        tt += d
        if (ts, v) in visited:
            break
        heappush(q, (tt, ts, v, 1))

print('\n'.join(map(str, ans[1:])))

Submission status: Time Limit Exceeded

Solution code:
import sys
from heapq import heappop, heappush

n, m, ss, *uvabcd = map(int, sys.stdin.buffer.read().split())
uuu = uvabcd[0:4 * m:4]
vvv = uvabcd[1:4 * m:4]
aaa = uvabcd[2:4 * m:4]
bbb = uvabcd[3:4 * m:4]
ccc = uvabcd[4 * m + 0::2]
ddd = uvabcd[4 * m + 1::2]
links = [set() for _ in range(n)]

for u, v, a, b in zip(uuu, vvv, aaa, bbb):
    u -= 1
    v -= 1
    links[u].add((v, a, b))
    links[v].add((u, a, b))

req = sum(sorted(aaa, reverse=True)[:n])
INF = 10 ** 18
ans = [INF] * n

q = [(0, ss, 0)]  # (time, silver, city)
visited = set()
fixed = 0
while q:
    t, s, v = heappop(q)
    if (s, v) in visited:
        continue
    visited.add((s, v))
    if ans[v] == INF:
        ans[v] = t
        fixed += 1
        if fixed == n:
            break

    for u, a, b in links[v]:
        if s < a:
            continue
        ns = s - a
        if (ns, u) in visited:
            continue
        heappush(q, (t + b, ns, u))

    ts = s
    tt = t
    c = ccc[v]
    d = ddd[v]
    while ts <= req:
        ts += c
        tt += d
        if (ts, v) in visited:
            break
        heappush(q, (tt, ts, v))

print('\n'.join(map(str, ans[1:])))

Submission status: Time Limit Exceeded

Solution code:
import sys
from heapq import heappop, heappush

n, m, ss, *uvabcd = map(int, sys.stdin.buffer.read().split())
uuu = uvabcd[0:4 * m:4]
vvv = uvabcd[1:4 * m:4]
aaa = uvabcd[2:4 * m:4]
bbb = uvabcd[3:4 * m:4]
ccc = uvabcd[4 * m + 0::2]
ddd = uvabcd[4 * m + 1::2]
links = [set() for _ in range(n)]

for u, v, a, b in zip(uuu, vvv, aaa, bbb):
    u -= 1
    v -= 1
    links[u].add((v, a, b))
    links[v].add((u, a, b))

INF = 10 ** 18
ans = [INF] * n

q = [(0, ss, 0)]  # (time, silver, city)
visited = set()
fixed = 0
while q:
    t, s, v = heappop(q)
    if (s, v) in visited:
        continue
    visited.add((s, v))
    if ans[v] == INF:
        ans[v] = t
        fixed += 1
        if fixed == n:
            break

    for u, a, b in links[v]:
        if s < a:
            continue
        ns = s - a
        if (ns, u) in visited:
            continue
        heappush(q, (t + b, ns, u))

    ts = s
    tt = t
    while ts < 2500:
        ts += ccc[v]
        tt += ddd[v]
        if (ts, v) not in visited:
            heappush(q, (tt, ts, v))
        else:
            break

print('\n'.join(map(str, ans[1:])))

Submission status: Time Limit Exceeded

Solution code:
import sys
from heapq import heappop, heappush

n, m, ss, *uvabcd = map(int, sys.stdin.buffer.read().split())
uuu = uvabcd[0:4 * m:4]
vvv = uvabcd[1:4 * m:4]
aaa = uvabcd[2:4 * m:4]
bbb = uvabcd[3:4 * m:4]
ccc = uvabcd[4 * m + 0::2]
ddd = uvabcd[4 * m + 1::2]
links = [set() for _ in range(n)]

for u, v, a, b in zip(uuu, vvv, aaa, bbb):
    u -= 1
    v -= 1
    links[u].add((v, a, b))
    links[v].add((u, a, b))

INF = 10 ** 18
ans = [INF] * n

q = [(0, ss, 0)]  # (time, silver, city)
visited = set()
fixed = 0
while q:
    t, s, v = heappop(q)
    if (s, v) in visited:
        continue
    visited.add((s, v))
    if ans[v] == INF:
        ans[v] = t
        fixed += 1
        if fixed == n:
            break

    for u, a, b in links[v]:
        if s < a:
            continue
        ns = s - a
        if (ns, u) in visited:
            continue
        heappush(q, (t + b, ns, u))

    ts = s
    tt = t
    while ts < 2500:
        ts += ccc[v]
        tt += ddd[v]
        if (ts, v) not in visited:
            heappush(q, (tt, ts, v))

print('\n'.join(map(str, ans[1:])))

Submission status: Time Limit Exceeded

Solution code:
import sys
from heapq import heappop, heappush

n, m, ss, *uvabcd = map(int, sys.stdin.buffer.read().split())
uuu = uvabcd[0:4 * m:4]
vvv = uvabcd[1:4 * m:4]
aaa = uvabcd[2:4 * m:4]
bbb = uvabcd[3:4 * m:4]
ccc = uvabcd[4 * m + 0::2]
ddd = uvabcd[4 * m + 1::2]
links = [set() for _ in range(n)]

for u, v, a, b in zip(uuu, vvv, aaa, bbb):
    u -= 1
    v -= 1
    links[u].add((v, a, b))
    links[v].add((u, a, b))

INF = 10 ** 18
ans = [INF] * n

q = [(0, ss, 0)]  # (time, silver, city)
visited = set()
fixed = 0
while q:
    t, s, v = heappop(q)
    if (s, v) in visited:
        continue
    visited.add((s, v))
    if ans[v] == INF:
        ans[v] = t
        fixed += 1
        if fixed == n:
            break

    for u, a, b in links[v]:
        if s < a:
            continue
        ns = s - a
        if (ns, u) in visited:
            continue
        heappush(q, (t + b, ns, u))

    ts = s
    tt = t
    while ts < 2500:
        ts += ccc[v]
        tt += ddd[v]
        nk = (tt, ts, v)
        if nk not in visited:
            heappush(q, (tt, ts, v))

print('\n'.join(map(str, ans[1:])))

Submission status: Time Limit Exceeded

Solution code:
#!usr/bin/env python3
from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.buffer.readline().split()]
def I(): return int(sys.stdin.buffer.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    n,m,s = LI()
    v = [[] for i in range(n)]
    M = 0
    for _ in range(m):
        x,y,a,b = LI()
        x -= 1
        y -= 1
        v[x].append((y,a,b))
        v[y].append((x,a,b))
        M += a
    g = LIR(n)
    d = defaultdict(lambda : float("inf"))
    d[(0,s)] = 0
    ans = [float("inf")]*n
    q = [(0,0,s)]
    k = 0
    while q:
        dx,x,s = heappop(q)
        if ans[x] == float("inf"):
            k += 1
            ans[x] = dx
            if k >= n:
                break
        c,e = g[x]
        for y,a,b in v[x]:
            if s < a:
                continue
            nd = dx+b
            ns = s-a
            if nd < d[(y,ns)]:
                d[(y,ns)] = nd
                heappush(q,(nd,y,ns))
        s += c
        dx += e
        while s <= M:
            for y,a,b in v[x]:
                if s < a:
                    continue
                nd = dx+b
                ns = s-a
                if nd < d[(y,ns)]:
                    d[(y,ns)] = nd
                    heappush(q,(nd,y,ns))
            s += c
            dx += e
    for i in ans[1:]:
        print(i)
    return

#Solve
if __name__ == "__main__":
    solve()

Submission status: Accepted

Solution code:
import sys
def input(): return sys.stdin.readline().strip()
def mapint(): return map(int, input().split())
sys.setrecursionlimit(10**9)

N, M, S = mapint()
graph = [{} for _ in range(N)]
for _ in range(M):
    u, v, a, t = mapint()
    graph[u-1][v-1] = (a, t)
    graph[v-1][u-1] = (a, t)

change = [list(mapint()) for _ in range(N)]
from heapq import heappop, heappush
# time, silver, vertex
Q = [(0, min(2500, S), 0)]
dist = [[10**18]*2501 for _ in range(N)]
dist[0][min(2500, S)] = 0

while Q:
    t, s, v = heappop(Q)
    rate, change_time = change[v]
    if s<2500 and dist[v][min(2500, s+rate)]>t+change_time:
        dist[v][min(2500, s+rate)] = t+change_time
        heappush(Q, (t+change_time, min(2500, s+rate), v))
    for nx in graph[v].keys():
        nx_s, nx_t = graph[v][nx]
        if nx_s<=s and dist[nx][s-nx_s]>t+nx_t:
            dist[nx][s-nx_s] = t+nx_t
            heappush(Q, (t+nx_t, s-nx_s, nx))
for i in range(1, N):
    print(min(dist[i]))

Submission status: Accepted

Solution code:
import sys
import heapq
def input(): return sys.stdin.readline().rstrip()


n, m, s = map(int, input().split())

graph = [[] for _ in range(n+1)]

maxcoin = 0

for i in range(m):
    u, v, a, b = map(int, input().split())
    graph[u].append((v, a, b))
    graph[v].append((u, a, b))
    maxcoin += a

ryougae = [0, 0]*(n+1)

for i in range(1, n+1):
    c, d = map(int, input().split())
    ryougae[i] = [c, d]


mindist = [[10**20]*(maxcoin+1) for _ in range(n+1)]
hq = []
heapq.heappush(hq, (0, 1, min(maxcoin, s)))
while hq:
    minute, city, coin = heapq.heappop(hq)
    if mindist[city][coin] != 10**20:
        continue
    mindist[city][coin] = minute
    for i, pay, length in graph[city]:
        if coin >= pay:
            if mindist[i][coin-pay] != 10**20:
                continue
            heapq.heappush(hq, (minute+length, i, coin-pay))
    if coin < maxcoin:
        kankin = min(maxcoin, ryougae[city][0]+coin)
        if mindist[city][kankin] != 10**20:
            continue
        heapq.heappush(hq, (minute+ryougae[city][1], city, kankin))

for i in range(2, n+1):
    print(min(mindist[i]))

Submission status: Accepted

Solution code:
import heapq
from heapq import heappush,heappop

class Heap1D:
    def __init__(self, shift=20):
        self.shift = shift
        self.data = []
        self.mask = (1<<shift)-1
    
    def push(self, x):
        a, b = x
        heapq.heappush(self.data, (a<<self.shift) | b)
    
    def pop(self):
        a = heapq.heappop(self.data)
        b = a & self.mask
        a >>= self.shift
        return a,b
      
    def __len__(self):
        return len(self.data)
      
def dijkstra(start = 0):
    d = [INF for i in range(len(G))]
    d[start] = 0
    que = Heap1D()
    que.push((0, start))

    while len(que):
        p = que.pop()
        v = p[1]
        if d[v] < p[0]:
            continue
        for u in G[v].keys():
            if d[u] > d[v] + G[v][u]:
                d[u] = d[v] + G[v][u]
                que.push((d[u], u))
    return d

N,M,S=map(int,input().split())
edges = [tuple(map(int,input().split())) for _ in range(M)]
cd = [tuple(map(int,input().split())) for _ in range(N)]
INF= 10**15
mod=55

mmax = sum([edges[i][2] for i in range(M)])
if S>mmax:
  S = mmax

G=[{} for _ in range((mmax+1)*mod+N+1)]
for i in range(M):
  u,v,a,b=edges[i]
  for p in range(a,mmax+1):
    G[u+p*mod][v+(p-a)*mod] = b
    G[v+p*mod][u+(p-a)*mod] = b
    
for i in range(N):
  c,d=cd[i]
  for p in range(mmax+1-c):
    G[i+1+p*mod][i+1+(p+c)*mod] = d
  
start = 1+S*mod
d = dijkstra(start)

ans=[INF]*(N+1)
for i in range(2,len(G)+1):
  v = i%mod
  if v>N or v<2:continue
  ans[v] = min(ans[v],d[i])
  
print(*ans[2:])

Submission status: Accepted

Solution code:
import heapq

N, M, S = map(int, input().split())
Map = [[] for _ in range(N)]
Ans = [[float('inf')] * 2500 for _ in range(N)]
for _ in range(M):
    u, v, a, b = map(int, input().split())
    u -= 1
    v -= 1
    Map[u].append((v, a, b))
    Map[v].append((u, a, b))

for i in range(N):
    c, d = map(int, input().split())
    Map[i].append((i, -c, d))

Q = []
heapq.heappush(Q, (0, 0, min(2499, S))) # 今の時間、場所、持っているお金
Ans[0][min(2499, S)] = 0
while Q:
    time, where, money = heapq.heappop(Q)
    for nex, cost, take in Map[where]:
        if cost > money:
            continue
        if Ans[nex][min(2499, money - cost)] > time + take:
            Ans[nex][min(2499, money - cost)] = time + take
            heapq.heappush(Q, (time + take, nex, money - cost))

for a in Ans[1:]:
    print(min(a))

Submission status: Accepted

Solution code:
import heapq
def dijkstra(s, n, g, d): # s: start, n: |V|, g; glaph 
    INF = 10**18
    d[s] = 0
    que = [] # (a,b): a... shortest dist, b... v
    heapq.heappush(que, (0, s))

    while que:
        dist, v = heapq.heappop(que)
        if d[v] < dist: continue # if v has been already used -> continue
        for next_v, cost in g[v]:
            if d[next_v] > d[v] + cost:
                d[next_v] = d[v] + cost
                heapq.heappush(que, (d[next_v], next_v))
    return d


def main():
    n,m,s = map(int, input().split())
    # g = [ [] for _ in range(n*2501+1)]
    g = {}
    dist = {}
    for i in range(n):
        for j in range(2501):
            g[(i,j)] = []
            dist[(i,j)] = 10**18
    for _ in range(m):
        u,v,a,b = map(int, input().split())
        u-=1
        v-=1
        for j in range(2501):
            if j < a: continue
            g[(u,j)].append(((v,j-a),b))
            g[(v,j)].append(((u,j-a),b))
            # g[u*2501+j].append((v*2501+j-a,b))
            # g[v*2501+j].append((u*2501+j-a,b))

    for i in range(n):
        c,d = map(int, input().split())
        for j in range(2501):
            maxc = min(2500,j+c)
            g[(i,j)].append(((i,maxc), d))

    sc = min(2500,s)
    s = (0,sc)
    dist = dijkstra(s, n*2501+1, g, dist)
    # print(dist)
    for i in range(1,n):
        ans = 10**18
        for j in range(2501):
            ans = min(ans, dist[(i,j)])
        print(ans)

if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
import heapq
def dijkstra(s, n, g): # s: start, n: |V|, g; glaph 
    INF = 10**18
    d = [INF] * n
    d[s] = 0
    que = [] # (a,b): a... shortest dist, b... v
    heapq.heappush(que, (0, s))

    while que:
        dist, v = heapq.heappop(que)
        if d[v] < dist: continue # if v has been already used -> continue
        for next_v, cost in g[v]:
            if d[next_v] > d[v] + cost:
                d[next_v] = d[v] + cost
                heapq.heappush(que, (d[next_v], next_v))
    return d


def main():
    n,m,s = map(int, input().split())
    g = [ [] for _ in range(n*2501+1)]
    for _ in range(m):
        u,v,a,b = map(int, input().split())
        u-=1
        v-=1
        for j in range(2501):
            if j < a: continue
            g[u*2501+j].append((v*2501+j-a,b))
            g[v*2501+j].append((u*2501+j-a,b))


    cdl = [(-1,-1)]
    for i in range(n):
        c,d = map(int, input().split())
        for j in range(2501):
            maxc = min(2500,j+c)
            g[i*2501+j].append((i*2501+maxc,d))

    s = min(2500,s)
    dist = dijkstra(s, n*2501+1, g)
    # print(dist)
    for i in range(1,n):
        ans = min(dist[i*2501:i*2501+2500])
        print(ans)


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
import bisect
import copy
import heapq
import math
import sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product
def input():
    return sys.stdin.readline()[:-1]
def ruiseki(lst):
    return [0]+list(accumulate(lst))
sys.setrecursionlimit(5000000)
mod=pow(10,9)+7
al=[chr(ord('a') + i) for i in range(26)]
direction=[[1,0],[0,1],[-1,0],[0,-1]]

n,m,s=map(int,input().split())
uvab=[list(map(int,input().split())) for i in range(m)]
cd=[list(map(int,input().split())) for i in range(n)]

def dijkstra(s,n):
    hq = [(0, s)]
    heapq.heapify(hq) # リストを優先度付きキューに変換
    cost = [float('inf')] * n # 行ったことのないところはinf
    cost[s] = 0 # 開始地点は0
    while hq:
        c, v = heapq.heappop(hq)
        if c > cost[v]: # コストが現在のコストよりも高ければスルー
            continue
        for d, u in e[v]:
            tmp = d + cost[v]
            if tmp < cost[u]:
                cost[u] = tmp
                heapq.heappush(hq, (tmp, u))
    return cost


e = [[] for _ in range(10000*(n+1))]
for i in range(n):
    c,d=cd[i]
    for j in range(2500):
        e[10000*i+j].append((d,10000*i+min(j+c,2500)))
    
for i in range(m):
    u,v,a,b=uvab[i]
    u,v = u-1, v-1
    for j in range(2500):
        if j-a>=0:
            e[10000*v+j].append((b,10000*u+j-a))
            e[10000*u+j].append((b,10000*v+j-a))
# print(e)
s=min(2499,s)
# print(s)
lst=dijkstra(s,10000*(n+1))
# print(lst)
for i in range(1,n):
    ans=float('inf')
    for j in range(2500):
        ans=min(ans,lst[10000*i+j])
    print(ans)

Submission status: Accepted

Solution code:
import sys
import itertools
# import numpy as np
import time
import math
import heapq
from collections import defaultdict
from collections import Counter
sys.setrecursionlimit(10 ** 7)
 
INF = 10 ** 18
MOD = 10 ** 9 + 7
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

# map(int, input().split())

import sys
import itertools
# import numpy as np
import time
import math
from heapq import heappop, heappush
from collections import defaultdict
from collections import Counter
from collections import deque
sys.setrecursionlimit(10 ** 7)
 
INF = 10 ** 18
MOD = 10 ** 9 + 7
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

# map(int, input().split())
N, M, S = map(int, input().split())
adj = [[] for _ in range(N)]
for i in range(M):
    u, v, a, b = map(int, input().split())
    u -= 1
    v -= 1
    adj[u].append((v, a, b))
    adj[v].append((u, a, b))
C = [0] * N
D = [0] * N
for i in range(N):
    C[i], D[i] = map(int, input().split())

MAX = 50 * 50 + 5
dp = [[INF] * (MAX + 1) for _ in range(N)]
q = []
def push(x, v, s):
    if s < 0:
        return
    if dp[v][s] <= x:
        return
    dp[v][s] = x
    heappush(q, (x, v, s))
s = min(MAX, S)
push(0, 0, s)
while len(q) > 0:
    x, v, s = heappop(q)
    if dp[v][s] != x:
        continue
    # 換金
    ns = min(s + C[v], MAX)
    push(x + D[v], v,  ns)
    # 隣の駅へ移動
    for u in adj[v]:
        push(x + u[2], u[0], s - u[1])

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

Submission status: Accepted

Solution code:
n,m,s=map(int,input().split())
uvab=[list(map(int,input().split())) for _ in range(m)]
cd=[list(map(int,input().split())) for _ in range(n)]
g=[[] for _ in range(n)]
maxs=0
for u,v,a,b in uvab:
    u,v=u-1,v-1
    g[u].append([v,a,b])
    g[v].append([u,a,b])
    maxs+=a

#「現在いる頂点、現在持っている銀貨枚数」を頂点とし、ダイクストラ法でとく。
from heapq import heappop,heappush
inf=float('inf')
ans=[[inf]*(maxs+1) for _ in range(n)]
s=min(s,maxs)
todo=[[0,0,s]]
ans[0][s]=0
while todo:
    t,v,ss=heappop(todo)
    if ans[v][ss]<t:continue
    for nv,na,nb in g[v]:
        if na>ss:continue
        if ans[nv][ss-na]>t+nb:
            heappush(todo,[t+nb,nv,ss-na])
            ans[nv][ss-na]=t+nb
    c,d=cd[v]
    nss=min(ss+c,maxs)
    if ans[v][nss]>t+d:
        heappush(todo,[t+d,v,nss])
        ans[v][nss]=t+d
for i in range(1,n):
    print(min(ans[i]))

Submission status: Accepted

Solution code:
n,m,s=map(int,input().split())
uvab=[list(map(int,input().split())) for _ in range(m)]
cd=[list(map(int,input().split())) for _ in range(n)]
g=[[] for _ in range(n)]
for u,v,a,b in uvab:
    u,v=u-1,v-1
    g[u].append([v,a,b])
    g[v].append([u,a,b])

#「現在いる頂点、現在持っている銀貨枚数」を頂点とし、ダイクストラ法でとく。
from heapq import heappop,heappush
inf=float('inf')
maxs=50*m
ans=[[inf]*(maxs+1) for _ in range(n)]
s=min(s,maxs)
todo=[[0,0,s]]
ans[0][s]=0
while todo:
    t,v,ss=heappop(todo)
    if ans[v][ss]<t:continue
    for nv,na,nb in g[v]:
        if na>ss:continue
        if ans[nv][ss-na]>t+nb:
            heappush(todo,[t+nb,nv,ss-na])
            ans[nv][ss-na]=t+nb
    c,d=cd[v]
    nss=min(ss+c,maxs)
    if ans[v][nss]>t+d:
        heappush(todo,[t+d,v,nss])
        ans[v][nss]=t+d
for i in range(1,n):
    print(min(ans[i]))

Submission status: Accepted

Solution code:
from heapq import heappush, heappop
def main():
    N, M, S = map(int, input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        u, v, a, b = map(int, input().split())
        u -= 1
        v -= 1
        G[u].append((v, a, b))
        G[v].append((u, a, b))
    CD = [list(map(int, input().split())) for _ in range(N)]
    distance = [[1<<62]*2501 for _ in range(N)]
    q = [(0, 0, min(S, 2500))]
    distance[0][min(S, 2500)] = 0
    while q:
        d, v, vs = heappop(q)
        if distance[v][vs] != d:
            continue

        vc, vd = CD[v]
        ud = d + vd
        us = vs + vc
        if us > 2500:
            us = 2500
        if distance[v][us] > ud:
            distance[v][us] = ud
            heappush(q, (ud, v, us))

        for u, fee, b in G[v]:
            if fee > vs:
                continue
            ud = d + b
            us = vs - fee
            if us > 2500:
                us = 2500
            if distance[u][us] > ud:
                distance[u][us] = ud
                heappush(q, (ud, u, us))
    print("\n".join(str(min(d)) for d in distance[1:]))

main()

Submission status: Accepted

Solution code:
import heapq

N, M, S = map(int, input().split())
Cost = [[] for _ in range(N)]
Change = [[0]*2 for _ in range(N)]
A_m = 0
for i in range(M):
    u, v, a, b = map(int, input().split())
    A_m = max(A_m, a)
    Cost[u-1].append([v-1, a, b])
    Cost[v-1].append([u-1, a, b])
for i in range(N):
    c, d = map(int, input().split())
    Change[i][0] = c
    Change[i][1] = d
if S > A_m*N:
    S = A_m*N

def dijkstra(N, start, Cost, Change):
    rich = [[] for _ in range(N+1)]
    Ans = [10**18]*N
    Ans[0] = 0
    minHeap = []
    used = [[10**18]*(A_m*N + 1) for _ in range(N)]
    used[start][S] = 0
    heapq.heappush(minHeap, (0, S, start))
    while minHeap:
        (c, hold, current) = heapq.heappop(minHeap)
        if rich[current] and rich[current][-1] >= hold:
            continue
        rich[current].append(hold)
        j = 1
        for i in range(N):
            if Ans[i] > c:
                j = 0
                break
        if j == 1:
            break
        for P in Cost[current]:
            road, a, b = P
            if hold >= a:
                if used[road][hold - a] > c + b:
                    used[road][hold - a] = c + b
                    heapq.heappush(minHeap, (c + b, hold - a, road))
                if Ans[road] > c + b:
                    Ans[road] = c + b
        if hold + Change[current][0] <= A_m*N:
            if used[current][hold + Change[current][0]] > c + Change[current][1]:
                heapq.heappush(minHeap, (c + Change[current][1], hold + Change[current][0], current))
    return Ans

T = dijkstra(N, 0, Cost, Change)
for i in T[1:]:
    print(i)