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.

Solution (Python):

import sys
input = lambda : sys.stdin.readline().rstrip()

import heapq
h = []
heapq.heapify(h)

n, m, s = list(map(int, input().split()))
a, b = [[None] * m for _ in range(2)]
c, d = [[None] * n for _ in range(2)]

ns = {}
uv2e = {}
for i in range(m):
    u,v,a[i],b[i] = list(map(int, input().split()))
    ns.setdefault(u-1, set())
    ns.setdefault(v-1, set())
    ns[u-1].add(v-1)
    ns[v-1].add(u-1)
    uv2e[u-1,v-1] = i
    uv2e[v-1,u-1] = i
for i in range(n):
    c[i], d[i] = list(map(int, input().split()))

maxs = max(a)*(n-1)
s = min(s, maxs)
state = (0, 0, s) 
ans = [[None] * (maxs+1) for _ in range(n)]
heapq.heappush(h, state)
count = 0
while h:
    count += 1
    dd, u, ss = heapq.heappop(h)

    if ans[u][ss] is not None and ans[u][ss] <= dd:
        continue
    ans[u][ss] = dd
    
    
    for v in ns[u]:
        e= uv2e[u,v]
        if ss<a[e] or ans[v][ss-a[e]] is not None:
            continue
        heapq.heappush(h, (dd + b[e], v, ss-a[e]))
    
    if ss+c[u] <= maxs:
        heapq.heappush(h, (dd + d[u], u, ss+c[u]))
    elif ss < maxs:
        heapq.heappush(h, (dd + d[u], u, maxs))

for item in ans[1:]:
    print(min(item))

Solution (Python):

import sys
input = lambda : sys.stdin.readline().rstrip()

import heapq
from collections import defaultdict
h = []
heapq.heapify(h)

n, m, s = list(map(int, input().split()))
a, b = [[None] * m for _ in range(2)]
c, d = [[None] * n for _ in range(2)]

ns = defaultdict(list)
uv2e = {}
for i in range(m):
    u,v,a[i],b[i] = list(map(int, input().split()))
    ns[u-1].append(v-1)
    ns[v-1].append(u-1)
    uv2e[u-1,v-1] = i
    uv2e[v-1,u-1] = i
for i in range(n):
    c[i], d[i] = list(map(int, input().split()))

maxs = max(a)*(n-1)
s = min(s, maxs)
state = (0, 0, s) 
ans = [[None] * (maxs+1) for _ in range(n)]
heapq.heappush(h, state)
count = 0
while h:
    count += 1
    dd, u, ss = heapq.heappop(h)

    if ans[u][ss] is not None and ans[u][ss] <= dd:
        continue
    ans[u][ss] = dd
    
    
    for v in ns[u]:
        e= uv2e[u,v]
        if ss<a[e] or ans[v][ss-a[e]] is not None:
            continue
        heapq.heappush(h, (dd + b[e], v, ss-a[e]))
    
    if ss+c[u] <= maxs:
        heapq.heappush(h, (dd + d[u], u, ss+c[u]))
    elif ss < maxs:
        heapq.heappush(h, (dd + d[u], u, maxs))

for item in ans[1:]:
    print(min(item))

Solution (Python):


import heapq
from collections import defaultdict
h = []
heapq.heapify(h)

n, m, s = list(map(int, input().split()))
a, b = [[None] * m for _ in range(2)]
c, d = [[None] * n for _ in range(2)]

ns = defaultdict(list)
uv2e = {}
for i in range(m):
    u,v,a[i],b[i] = list(map(int, input().split()))
    ns[u-1].append(v-1)
    ns[v-1].append(u-1)
    uv2e[u-1,v-1] = i
    uv2e[v-1,u-1] = i
for i in range(n):
    c[i], d[i] = list(map(int, input().split()))

maxs = max(a)*(n-1)
s = min(s, maxs)
state = (0, 0, s) 
ans = [[None] * (maxs+1) for _ in range(n)]
heapq.heappush(h, state)
count = 0
while h:
    count += 1
    dd, u, ss = heapq.heappop(h)

    if ans[u][ss] is not None and ans[u][ss] <= dd:
        continue
    ans[u][ss] = dd
    
    
    for v in ns[u]:
        e= uv2e[u,v]
        if ss<a[e] or ans[v][ss-a[e]] is not None:
            continue
        heapq.heappush(h, (dd + b[e], v, ss-a[e]))
    
    if ss+c[u] <= maxs:
        heapq.heappush(h, (dd + d[u], u, ss+c[u]))
    elif ss < maxs:
        heapq.heappush(h, (dd + d[u], u, maxs))

for item in ans[1:]:
    print(min(item))

Solution (Python):
import numpy as np
from scipy.sparse import lil_matrix, csr_matrix
from scipy.sparse.csgraph import shortest_path
M=49*50+1
n,m,s=map(int,input().split())
s=min(s,M-1)
G=lil_matrix((n*M,n*M))
for _ in range(m):
    a,b,silver,time=map(int,input().split())
    a-=1
    b-=1
    for i in range(silver,M):
        G[a*M+i,b*M+i-silver]=time
        G[b*M+i,a*M+i-silver]=time
for i in range(n):
    silver,time=map(int,input().split())
    for j in range(M-silver):
        G[i*M+j,i*M+j+silver]=time
G=G.tocsr()
G=shortest_path(G,method='D',indices=s) 

for i in range(1,n):
    ans=np.min(G[i*M:i*M+M])
    print(int(ans))

Solution (Python):
import numpy as np
from scipy.sparse import lil_matrix, csr_matrix
from scipy.sparse.csgraph import shortest_path
M=49*50+1
n,m,s=map(int,input().split())
s=min(s,M-1)
G=lil_matrix((n*M,n*M))
for _ in range(m):
    a,b,silver,time=map(int,input().split())
    a-=1
    b-=1
    for i in range(silver,M):
        G[a*M+i,b*M+i-silver]=time
        G[b*M+i,a*M+i-silver]=time
for i in range(n):
    silver,time=map(int,input().split())
    for j in range(M-1):
        G[i*M+j,i*M+min(j+silver,M-1)]=time
G=G.tocsr()
G=shortest_path(G,method='D',indices=s)

for i in range(1,n):
    ans=np.min(G[i*M:i*M+M])
    print(int(ans))

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

edges = [[] for _ in range(n)]
for _ in range(m):
    u, v, a, b = map(int, input().split())
    u, v = u-1, v-1
    edges[u].append((v, a, b))
    edges[v].append((u, a, b))

banks = tuple(tuple(map(int, input().split())) for _ in range(n))

max_s = 50 * (n-1)

s = min(s, max_s)

import heapq

h = []
dp = [[float('inf')] * (max_s+1) for _ in range(n)]
ans = [float('inf')] * n

heapq.heappush(h, (0, 0, s))
while h:
    time, node, coin = heapq.heappop(h)
    if time >= dp[node][coin]:
        continue
    dp[node][coin] = time
    if time < ans[node]:
        ans[node] = time

    c, d = banks[node]
    if coin < max_s:
        heapq.heappush(h, (time+d, node, min(coin + c, max_s)))

    for n, a, b in edges[node]:
        new_time = time + b
        new_coin = coin - a
        if new_coin < 0 or new_time >= dp[n][new_coin]:
            continue
        heapq.heappush(h, (new_time, n, new_coin))

for a in ans[1:]:
    print(a)

Solution (Python):
def main():
    import heapq

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

    edges = [[] for _ in range(n)]
    max_cost = 0
    for _ in range(m):
        from_, to, cost, time = map(int, input().split())
        edges[from_-1].append((to-1, cost, time))
        edges[to-1].append((from_-1, cost, time))
        if cost > max_cost:
            max_cost = cost

    banks = []
    for i in range(n):
        coin, time = map(int, input().split())
        banks.append((coin, time))

    max_coin = max_cost * (n-1)
    if s > max_coin:
        s = max_coin

    INF = float('INF')
    DP = [[INF] * (max_coin+1) for _ in range(n)]
    DP[0][s] = 0

    def push_todo(node, coin, time):
        if coin < 0:
            return
        if time >= DP[node][coin]:
            return
        heapq.heappush(todo, (time, node, coin))
        DP[node][coin] = time

    def charge(node, current_coin, current_time):
        coin, time = banks[node]
        new_coin = current_coin + coin
        if new_coin > max_coin:
            new_coin = max_coin
        push_todo(node, new_coin, current_time+time)

    todo = [(0, 0, s)]  
    while todo:
        current_time, node, current_coin = heapq.heappop(todo)
        if current_time > DP[node][current_coin]:
            continue

        charge(node, current_coin, current_time)

        for to, cost, time in edges[node]:
            push_todo(to, current_coin-cost, current_time+time)

    for node in range(1, n):
        print(min(DP[node]))


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    import heapq

    n, m, s = map(int, input().split())
    if s >= 2500:
        s = 2499

    edges = [[] for _ in range(n)]
    for _ in range(m):
        from_, to, cost, time = map(int, input().split())
        edges[from_-1].append((to-1, cost, time))
        edges[to-1].append((from_-1, cost, time))

    banks = []
    for i in range(n):
        coin, time = map(int, input().split())
        banks.append((coin, time))

    INF = float('INF')
    DP = [[INF] * 2500 for _ in range(n)]
    DP[0][s] = 0
    ans = [INF] * n

    def push_todo(node, coin, time):
        if coin < 0:
            return
        if time >= DP[node][coin]:
            return
        heapq.heappush(todo, (time, node, coin))
        DP[node][coin] = time

    def charge(node, current_coin, current_time):
        coin, time = banks[node]
        new_coin = current_coin + coin
        if new_coin >= 2500:
            new_coin = 2499
        push_todo(node, new_coin, current_time+time)

    todo = [(0, 0, s)]  
    while todo:
        current_time, node, current_coin = heapq.heappop(todo)
        if current_time > DP[node][current_coin]:
            continue

        if current_time < ans[node]:
            ans[node] = current_time

        charge(node, current_coin, current_time)

        for to, cost, time in edges[node]:
            push_todo(to, current_coin-cost, current_time+time)

    for a in ans[1:]:
        print(a)


if __name__ == '__main__':
    main()

Solution (Python):
def main():    
    import heapq
    
    n, m, s = map(int, input().split())
    if s >= 2500:
        s = 2499
    
    edges = [[] for _ in range(n)]
    for _ in range(m):
        from_, to, cost, time = map(int, input().split())
        edges[from_-1].append((to-1, cost, time))
        edges[to-1].append((from_-1, cost, time))
    
    banks = []
    for i in range(n):
        coin, time = map(int, input().split())
        banks.append((coin, time))
    
    INF = float('INF')
    DP = [[INF] * 2500 for _ in range(n)]
    ans = [INF] * n
    
    def push_todo(node, coin, time):
        if coin < 0:
            return
        if time >= DP[node][coin]:
            return
        heapq.heappush(todo, (time, node, coin))
    
    def charge(node, current_coin, current_time):
        coin, time = banks[node]
        new_coin = current_coin + coin
        if new_coin >= 2500:
            new_coin = 2499
        push_todo(node, new_coin, current_time+time)
    
    todo = [(0, 0, s)]
    while todo:
        current_time, node, current_coin = heapq.heappop(todo)
        if current_time >= DP[node][current_coin]:
            continue
    
        if current_time < ans[node]:
            ans[node] = current_time
    
        DP[node][current_coin] = current_time
        charge(node, current_coin, current_time)
    
        for to, cost, time in edges[node]:
            push_todo(to, current_coin-cost, current_time+time)
    
    for a in ans[1:]:
        print(a)


if __name__ == '__main__':
    main()

Solution (Python):
import heapq


n, m, s = map(int, input().split())
if s >= 2500:
    s = 2499

edges = [[] for _ in range(n)]
for _ in range(m):
    from_, to, cost, time = map(int, input().split())
    edges[from_-1].append((to-1, cost, time))
    edges[to-1].append((from_-1, cost, time))

banks = []
for i in range(n):
    coin, time = map(int, input().split())
    banks.append((coin, time))

INF = float('INF')
DP = [[INF] * 2500 for _ in range(n)]
ans = [INF] * n


def push_todo(node, coin, time):
    if coin < 0:
        return
    if time >= DP[node][coin]:
        return
    heapq.heappush(todo, (time, node, coin))


def charge(node, current_coin, current_time):
    coin, time = banks[node]
    new_coin = current_coin + coin
    if new_coin >= 2500:
        new_coin = 2499
    push_todo(node, new_coin, current_time+time)


todo = [(0, 0, s)]
while todo:
    current_time, node, current_coin = heapq.heappop(todo)
    if current_time >= DP[node][current_coin]:
        continue

    if current_time < ans[node]:
        ans[node] = current_time

    DP[node][current_coin] = current_time
    charge(node, current_coin, current_time)

    for to, cost, time in edges[node]:
        push_todo(to, current_coin-cost, current_time+time)

for a in ans[1:]:
    print(a)

Solution (Python):
import heapq


n, m, s = map(int, input().split())
if s >= 2500:
    s = 2499

edges = [[] for _ in range(n)]
for _ in range(m):
    from_, to, cost, time = map(int, input().split())
    edges[from_-1].append((to-1, cost, time))
    edges[to-1].append((from_-1, cost, time))

banks = [(0, 0) for _ in range(n)]
for i in range(n):
    coin, time = map(int, input().split())
    banks[i] = (coin, time)

INF = float('INF')
DP = [INF] * (n * 2500)
ans = [INF] * n


def to_one_dimension(node, coin):
    return node * 2500 + coin


def push_todo(node, coin, time):
    if coin < 0:
        return
    if time >= DP[to_one_dimension(node, coin)]:
        return
    heapq.heappush(todo, (time, node, coin))


def charge(node, current_coin, current_time):
    coin, time = banks[node]
    new_coin = current_coin + coin
    if new_coin >= 2500:
        new_coin = 2499
    push_todo(node, new_coin, current_time+time)


todo = [(0, 0, s)]
while todo:
    current_time, node, current_coin = heapq.heappop(todo)
    if current_time < ans[node]:
        ans[node] = current_time

    one_d_idx = to_one_dimension(node, current_coin)
    if current_time >= DP[one_d_idx]:
        continue

    DP[one_d_idx] = current_time
    charge(node, current_coin, current_time)

    for to, cost, time in edges[node]:
        push_todo(to, current_coin-cost, current_time+time)

for a in ans[1:]:
    print(a)

Solution (Python):
from heapq import heappush, heappop, heapify
from collections import deque, defaultdict, Counter
import itertools
from itertools import permutations, combinations, accumulate, product
import sys
import bisect
import string
import math
import time

def I(): return int(input())
def S(): return input()
def MI(): return map(int, input().split())
def MS(): return map(str, input().split())
def LI(): return [int(i) for i in input().split()]
def LI_(): return [int(i)-1 for i in input().split()]
def StoI(): return [ord(i)-97 for i in input()]
def ItoS(nn): return chr(nn+97)
def input(): return sys.stdin.readline().rstrip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

class NeighborList():
    def __init__(self):
        self.neighbor = {}


class Dijkstra(object):
    def dijkstra(self, adj, start, goal=None):
        '''
        ダイクストラアルゴリズムによる最短経路を求めるメソッド
        入力
        adj: adj[i][j]の値が頂点iから頂点jまでの距離(頂点iから頂点jに枝がない場合，値はfloat('inf'))となるような2次元リスト(正方行列)
        start: 始点のID
        goal: オプション引数．終点のID
        出力
        goalを引数に持つ場合，startからgoalまでの最短経路を格納したリストを返す
        持たない場合は，startから各頂点までの最短距離を格納したリストを返す
        '''
        dist = {} 
        prev = {} 

        dist[start] = 0
        prev[start] = 0
        q = []                  
        heappush(q, (0, start)) 

        while len(q) != 0:
            prov_cost, src = heappop(q) 

            
            if dist[src] < prov_cost:
                continue

            
            for dest in adj[src].neighbor.keys():
                cost = adj[src].neighbor[dest]

                if dest in dist.keys():
                    if dist[dest] > dist[src] + cost:
                        dist[dest] = dist[src] + cost 
                        heappush(q, (dist[dest], dest)) 
                        prev[dest] = src                      
                else:
                    dist[dest] = dist[src] + cost 
                    heappush(q, (dist[dest], dest)) 
                    prev[dest] = src                      

        if goal is not None:
            return self.get_path(start,goal, prev)
        else:
            return dist

    def get_path(self, start, goal, prev):
        '''
        始点startから終点goalまでの最短経路を求める
        '''
        path = [goal]           
        dest = goal

        
        while prev[dest] != start:
            path.append(prev[dest])
            dest = prev[dest]

        path.append(start)

        
        return list(reversed(path))


yn = {False: 'No', True: 'Yes'}
YN = {False: 'NO', True: 'YES'}
MOD = 10**9+7
inf = float('inf')
IINF = 10**19
l_alp = string.ascii_lowercase
u_alp = string.ascii_uppercase
ts = time.time()
sys.setrecursionlimit(10**6)
nums = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

show_flg = False


MX = 2500

def trans(e, s):
    return MX * e + s


def main():
    N, M, S = MI()
    U = [0] * M
    V = [0] * M
    A = [0] * M
    B = [0] * M
    C = [0] * N
    D = [0] * N
    edges = [[] for i in range(N)]
    
    adj = {i:NeighborList() for i in range(N * MX)}

    for i in range(M):
        U[i], V[i], A[i], B[i] = MI()
        U[i] -= 1
        V[i] -= 1
        edges[U[i]].append((V[i], i))
        edges[V[i]].append((U[i], i))

    for i in range(N):
        C[i], D[i] = MI()

    for i in range(N):
        for j in range(0, MX):
            to = min(j + C[i], MX-1)
            
            adj[trans(i, j)].neighbor[trans(i, to)] = D[i]
            for pair in edges[i]:
                to = pair[0]
                idx = pair[1]
                if j - A[idx] >= 0:
                    
                    adj[trans(i, j)].neighbor[trans(to, j - A[idx])] = B[idx]

    S = min(2499, S)
    
    d = Dijkstra()
    ret = d.dijkstra(adj, trans(0, S))
    

    
    
    

    for i in range(1, N):
        ans = IINF
        for j in range(MX):
            
            
            ans = min(ans, ret[trans(i, j)])
        print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import heapq
import sys

input = sys.stdin.readline

inf = 10**13

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

data = [[] for _ in range(N)]

sumA = 0

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

P = sumA

C = [0]*N
D = [0]*N

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

dist = [[inf]*(P+1) for _ in range(N)]



q = [(0,0,min(S,P))]
heapq.heapify(q)

while q:
    v = heapq.heappop(q)
    if v[0] >= dist[v[1]][v[2]]:
        continue
    dist[v[1]][v[2]] = v[0]

    if v[2] + C[v[1]] <= P:
        if dist[v[1]][v[2]+C[v[1]]] == inf:
            heapq.heappush(q,(v[0]+D[v[1]],v[1],v[2]+C[v[1]]))

    for x in data[v[1]]:
        if x[2] > v[2]:
            continue
        if dist[x[1]][v[2]-x[2]] == inf:
            heapq.heappush(q,(v[0]+x[0],x[1],v[2]-x[2]))
    
    
    
    
    
    

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

Solution (Python):
from heapq import heappop, heappush
import sys
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline


phi = lambda city, silver: city * 2501 + silver
psi = lambda x: (x//2501, x % 2501)


n, m, s = map(int, input().split())
g = [[] for _ in range(n*2501+1)]

for i in range(m):
    u, v, a, b = map(int, input().split())
    for j in range(2501):
        if j-a >= 0:
            g[phi(u-1, j)].append((phi(v-1, j-a), b))
            g[phi(v-1, j)].append((phi(u-1, j-a), b))

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


def dijkstra(s, n, g):
    
    
    
    d = [10**18] * n
    d[s] = 0
    q = [(0, s)]
    while q:
        dist_u, u = heappop(q)
        if d[u] < dist_u:
            continue
        for v, c in g[u]:  
            if d[v] > dist_u + c:
                d[v] = dist_u + c
                heappush(q, (d[v], v))
    return d


s = min(s, 2500)
d = dijkstra(phi(0, s), n*2501+1, g)

for i in range(1, n):
    print(min(d[phi(i, 0):phi(i+1, 0)]))

Solution (Python):
import sys
input =sys.stdin.readline
import heapq

def dijkstra(edge, start):
    n = len(edge)
    dist = [float("inf")]*n
    dist[start] = 0
    que = [(0, start)]
    while que:
        d, v = heapq.heappop(que)
        if dist[v] < d:
            continue
        for nv, nd in edge[v]:
            if dist[nv] > d + nd:
                dist[nv] = d + nd
                heapq.heappush(que, (dist[nv], nv))
    return dist

n, m, s = map(int, input().split())
G = [[] for _ in range(n)]
if s >= 2500:
  for _ in range(m):
    u, v, a, b = map(int, input().split())
    u -= 1
    v -= 1
    G[u].append((v, b))
    G[v].append((u, b))
  L = dijkstra(G, 0)
else:
  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)]
  edge = [[] for _ in range(n*2500)]
  for i in range(n):
    c, d = CD[i]
    for k in range(2500):
      for v, a, b in G[i]:
        if k >= a:
          edge[2500*i+k].append((2500*v+(k-a), b))
      if k+c < 2500:
        edge[2500*i+k].append((2500*i+(k+c), d))
  dist = dijkstra(edge, s)
  L = [0]*n
  for i in range(n):
    L[i] = min(dist[2500*i:2500*(i+1)])
print(*L[1:], sep="\n")

Solution (Python):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from operator import mul


sys.setrecursionlimit(2147483647)
INF = 10 ** 13
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
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)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


n, m, s = LI()
G = [[] for _ in range(n)]
for _ in range(m):
    u, v, a, b = LI()
    G[u - 1] += [(v - 1, a, b)]
    G[v - 1] += [(u - 1, a, b)]

change = LIR(n)

def dijkstra(s):
    hq = [(0, 0, s)]
    dist = [[INF] * 2451 for _ in range(n)]
    dist[0][s] = 0
    while hq:
        t, u, coin = heappop(hq)
        if t > dist[u][coin]:
            continue
        if t + change[u][1] < dist[u][min(2450, coin + change[u][0])]:
            dist[u][min(2450, coin + change[u][0])] = t + change[u][1]
            heappush(hq, (t + change[u][1], u, min(2450, coin + change[u][0])))
        for v, c, d in G[u]:
            if coin - c >= 0 and t + d < dist[v][coin - c]:
                dist[v][coin - c] = t + d
                heappush(hq, (t + d, v, coin - c))
    return dist

D = dijkstra(min(2450, s))
for t in range(1, n):
    print(min(D[t]))

Solution (Python):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from operator import mul


sys.setrecursionlimit(2147483647)
INF = 10 ** 13
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
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)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007


n, m, s = LI()
G = [[] for _ in range(n)]
for _ in range(m):
    u, v, a, b = LI()
    G[u - 1] += [(v - 1, a, b)]
    G[v - 1] += [(u - 1, a, b)]

change = LIR(n)

def dijkstra(s):
    hq = [(0, 0, s)]
    dist = [[INF] * 2451 for _ in range(n)]
    dist[0][s] = 0
    while hq:
        t, u, coin = heappop(hq)
        if t > dist[u][coin]:
            continue
        dist[u][coin] = t
        if t + change[u][1] < dist[u][min(2450, coin + change[u][0])]:
            dist[u][min(2450, coin + change[u][0])] = t + change[u][1]
            heappush(hq, (t + change[u][1], u, min(2450, coin + change[u][0])))
        for v, c, d in G[u]:
            if coin - c >= 0 and t + d < dist[v][coin - c]:
                dist[v][coin - c] = t + d
                heappush(hq, (t + d, v, coin - c))
    return dist

D = dijkstra(min(2450, s))
for t in range(1, n):
    print(min(D[t]))

Solution (Python):
import sys
from collections import defaultdict
from heapq import heappush, heappop, heapify
input = sys.stdin.readline

INF = 10**19
n, m, s = map(int, input().split())
edges = defaultdict(lambda: defaultdict(lambda: [INF, INF]))
cd = []
max_a = 0

for i in range(m):
    u, v, a, b = map(int, input().split())
    max_a = max(max_a, a)
    edges[u-1][v-1] = [a, b]
    edges[v-1][u-1] = [a, b]

for i in range(n):
    c, d = map(int, input().split())
    cd.append([c, d])



SIZE = max_a * n + 1

if s > SIZE:
    s = SIZE
nodes = [[INF for _ in range(SIZE+1)] for _ in range(n)]
nodes[0][s] = 0

def dijakstra():
    goals = set({0})
    que = [(0, 0, s)]
    heapify(que)
    while 10**6 > len(que) > 0:
        if len(goals) >= n:
            break
        cost, num, silver = heappop(que)
        if num not in goals:
            goals.add(num)
        c, d = cd[num]
        s_tmp = min(SIZE, silver+c)
        if silver < SIZE and s_tmp != silver:
            if nodes[num][s_tmp] > cost + d:
                heappush(que, (cost + d, num, s_tmp))
                nodes[num][s_tmp] = min(nodes[num][s_tmp], cost + d)
        for v in edges[num].keys():
            a, b = edges[num][v]
            if silver >= a:
                if nodes[v][silver-a] > cost + b:
                    heappush(que, (cost + b, v, silver - a))
                    nodes[v][silver - a] = min(nodes[v][silver - a], cost + b)

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