Problem:
 Score : 400 points    Problem Statement Kenkoooo is planning a trip in Republic of Snuke.
In this country, there are n cities and m trains running.
The cities are numbered 1 through n , and the i -th train connects City u_i and v_i bidirectionally.
Any city can be reached from any city by changing trains.  Two currencies are used in the country: yen and snuuk.
Any train fare can be paid by both yen and snuuk.
The fare of the i -th train is a_i yen if paid in yen, and b_i snuuk if paid in snuuk.  In a city with a money exchange office, you can change 1 yen into 1 snuuk.
However, when you do a money exchange, you have to change all your yen into snuuk.
That is, if Kenkoooo does a money exchange when he has X yen, he will then have X snuuk.
Currently, there is a money exchange office in every city, but the office in City i will shut down in i years and can never be used in and after that year.  Kenkoooo is planning to depart City s with 10^{15} yen in his pocket and head for City t , and change his yen into snuuk in some city while traveling.
It is acceptable to do the exchange in City s or City t .  Kenkoooo would like to have as much snuuk as possible when he reaches City t by making the optimal choices for the route to travel and the city to do the exchange.
For each i=0,...,n-1 , find the maximum amount of snuuk that Kenkoooo has when he reaches City t if he goes on a trip from City s to City t after i years.
You can assume that the trip finishes within the year.      Constraints  2 \leq n \leq 10^5  1 \leq m \leq 10^5  1 \leq s,t \leq n  s \neq t  1 \leq u_i < v_i \leq n  1 \leq a_i,b_i \leq 10^9  If i\neq j , then u_i \neq u_j or v_i \neq v_j .  Any city can be reached from any city by changing trains.  All values in input are integers.         Input Input is given from Standard Input in the following format:  n  m  s  t  u_1  v_1  a_1  b_1  :  u_m  v_m  a_m  b_m       Output Print n lines.
In the i -th line, print the maximum amount of snuuk that Kenkoooo has when he reaches City t if he goes on a trip from City s to City t after i-1 years.        Sample Input 1 4 3 2 3
1 4 1 100
1 2 1 10
1 3 20 1      Sample Output 1 999999999999998
999999999999989
999999999999979
999999999999897  After 0 years, it is optimal to do the exchange in City 1 . After 1 years, it is optimal to do the exchange in City 2 . Note that City 1 can still be visited even after the exchange office is closed.
Also note that, if it was allowed to keep 1 yen when do the exchange in City 2 and change the remaining yen into snuuk, we could reach City 3 with 999999999999998 snuuk, but this is NOT allowed. After 2 years, it is optimal to do the exchange in City 3 . After 3 years, it is optimal to do the exchange in City 4 .
Note that the same train can be used multiple times.       Sample Input 2 8 12 3 8
2 8 685087149 857180777
6 7 298270585 209942236
2 4 346080035 234079976
2 5 131857300 22507157
4 8 30723332 173476334
2 6 480845267 448565596
1 4 181424400 548830121
4 5 57429995 195056405
7 8 160277628 479932440
1 6 475692952 203530153
3 5 336869679 160714712
2 7 389775999 199123879      Sample Output 2 999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994
999999574976994

Solution (Python):
import heapq, sys
def input():
    return sys.stdin.readline()[:-1]

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

yen_edge = [[] for _ in range(n)]
snuke_edge = [[] for _ in range(n)]

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

class DijkstraList():
    
    
    def __init__(self, adj, start):
        self.list = adj
        self.start = start
        self.size = len(adj)

    def solve(self):
        self.dist = [float("inf") for _ in range(self.size)]
        self.dist[self.start] = 0
        self.prev = [-1 for _ in range(self.size)]
        self.q = []
        self.cnt = 0

        heapq.heappush(self.q, (0, self.start))

        while self.q and self.cnt < self.size:
            u_dist, u = heapq.heappop(self.q)
            if self.dist[u] < u_dist:
                continue
            for v, w in self.list[u]:
                if self.dist[v] > u_dist + w:
                    self.dist[v] = u_dist + w
                    self.prev[v] = u
                    heapq.heappush(self.q, (self.dist[v], v))

            self.cnt += 1

        return

    def distance(self, goal):
        return self.dist[goal]

    def path(self, goal):
        self.path = [goal]
        while self.path[-1] != self.start:
            self.path.append(self.prev[self.path[-1]])
        return self.path[::-1]

yen = DijkstraList(yen_edge, s - 1)
snuke = DijkstraList(snuke_edge, t - 1)
yen.solve()
snuke.solve()
ans_list = []

for i in range(n):
	ans_list.append(yen.distance(i) + snuke.distance(i))

ans = []

ans.append(10 ** 15 - ans_list[n - 1])

for i in range(1, n):
	if ans_list[n - i - 1] > ans_list[n - i]:
		ans_list[n - i - 1] = ans_list[n - i]
	ans.append(10 ** 15 - ans_list[n - i - 1])

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

Solution (Python):
import heapq
import sys
n, m, s, t = [int(i) for i in input().split()]
s -= 1
t -= 1
snuuk_dict = dict()
yen_dict = dict()
snuuk_que = []
yen_que = []
for i in range(m):
    u, v, a, b = [int(i) for i in sys.stdin.readline().split()]
    u -= 1
    v -= 1
    if snuuk_dict.get(u) is None:
        snuuk_dict[u] = []
        yen_dict[u] = []
    if snuuk_dict.get(v) is None:
        snuuk_dict[v] = []
        yen_dict[v] = []
    snuuk_dict[u].append([b, u, v])
    snuuk_dict[v].append([b, v, u])
    yen_dict[u].append([a, u, v])
    yen_dict[v].append([a, v, u])

for i in snuuk_dict[t]:
    heapq.heappush(snuuk_que, i)
for i in yen_dict[s]:
    heapq.heappush(yen_que, i)
snuuk_ls = [-1 for i in range(n)]
yen_ls = [-1 for i in range(n)]
yen_ls[s] = 0
snuuk_ls[t] = 0
while len(yen_que) > 0:
    a, u, v = heapq.heappop(yen_que)
    if yen_ls[v] != -1:
        continue
    yen_ls[v] = a
    for i in yen_dict[v]:
        if yen_ls[i[2]] == -1:
            heapq.heappush(yen_que, [i[0] + yen_ls[v], i[1], i[2]])
while len(snuuk_que) > 0:
    b, v, u = heapq.heappop(snuuk_que)
    if snuuk_ls[u] != -1:
        continue
    snuuk_ls[u] = b
    for i in snuuk_dict[u]:
        if snuuk_ls[i[2]] == -1:
            heapq.heappush(snuuk_que,  [i[0] + snuuk_ls[u], i[1], i[2]])
sum_ls = [10** 15 - (i + j) for i, j in zip(snuuk_ls, yen_ls)]
_max = 0
for i in range(n):
    _max = sum_ls[-1-i] if sum_ls[-1-i] > _max else _max
    sum_ls[-i-1] = _max
for i in range(n):
    print(sum_ls[i])

Solution (Python):
from heapq import heapify, heappop, heappush
from collections import defaultdict

n,m,s,t = map(int,input().split())
s-=1
t-=1
edge_a = defaultdict(set)
edge_b = defaultdict(set)
for i in range(m):
    u,v,a,b = map(int, input().split())
    u -= 1
    v -= 1
    edge_a[u].add((v, a))
    edge_a[v].add((u, a))
    edge_b[u].add((v, b))
    edge_b[v].add((u, b))

def djikstra(s,edges):
    n = len(edges)
    visited = {}
    q = []
    while len(visited) != n:
        if len(visited) == 0:
            next_p = s
            visited[s] = 0
        else:
            while q:
                cost, to_ = heappop(q)
                if to_ not in visited:
                    visited[to_] = cost
                    next_p = to_
                    break

        for to_, cost in edges[next_p]:
            if cost >= 0 and to_ not in visited:
                heappush(q, (visited[next_p] + cost, to_))
    return visited

cost_a = djikstra(s,edge_a)
cost_b = djikstra(t, edge_b)

ans = []
for i in range(n)[::-1]:
    nokori = 10**15 - cost_a[i] - cost_b[i]
    if len(ans) == 0:
        ans.append(nokori)
    else:
        ans.append(max(nokori, ans[-1]))
print(*ans[::-1], sep="\n")

Solution (Python):


"""
参考：https://img.atcoder.jp/soundhound2018-summer-qual/editorial.pdf
　　　https://ikatakos.com/pot/programming_algorithm/contest_history/atcoder/2018/0707_soundhound2018_summer_qual
"""

import sys, re
from collections import deque, defaultdict, Counter
from math import sqrt, hypot, factorial, pi, sin, cos, radians, log10
if sys.version_info.minor >= 5: from math import gcd
else: from fractions import gcd 
from heapq import heappop, heappush, heapify, heappushpop
from bisect import bisect_left, bisect_right
from itertools import permutations, combinations, product, accumulate
from operator import itemgetter, mul, xor
from copy import copy, deepcopy
from functools import reduce, partial
from fractions import Fraction
from string import ascii_lowercase, ascii_uppercase, digits

def input(): return sys.stdin.readline().strip()
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 ceil(x, y=1): return int(-(-x // y))
def round(x): return int((x*2+1) // 2)
def fermat(x, y, MOD): return x * pow(y, MOD-2, MOD) % MOD
def lcm(x, y): return (x * y) // gcd(x, y)
def lcm_list(nums): return reduce(lcm, nums, 1)
def gcd_list(nums): return reduce(gcd, nums, nums[0])
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
MOD = 10 ** 9 + 7


def dijkstra(N: int, nodes: list, src: int) -> list:
    
    
    res = [float('inf')] * N
    
    que = [(0, src)]
    res[src] = 0
    
    while len(que) != 0:
        
        dist, cur = heappop(que)
        
        for nxt, cost in nodes[cur]:
            
            if res[cur] + cost < res[nxt]:
                res[nxt] = res[cur] + cost
                
                heappush(que, (res[nxt], nxt))
    
    return res

N,M,S,T=MAP()
nodes1=[[] for i in range(N)]
nodes2=[[] for i in range(N)]
for i in range(M):
    u,v,a,b=MAP()
    
    nodes1[u-1].append((v-1,a))
    nodes1[v-1].append((u-1,a))
    
    nodes2[u-1].append((v-1,b))
    nodes2[v-1].append((u-1,b))

yen=dijkstra(N,nodes1,S-1)
snuk=dijkstra(N,nodes2,T-1)

ans=[0]*N
mn=INF

for i in range(N-1, -1, -1):
    ans[i]=mn=min(mn, yen[i]+snuk[i])

for i in range(N):
    print(1000000000000000-ans[i])

Solution (Python):

import heapq
n,m,s,t = map(int, input().split())
g = [[] for _ in range(n+1)]
for _ in range(m):
    u,v,a,b = map(int, input().split())
    g[u].append((v,(a,b)))
    g[v].append((u,(a,b)))

inf = 10**18
def dijkstra(s, currency):
    d = [inf]*(n+1)
    d[s] = 0

    que = [(d[s],s)]
    heapq.heapify([que])
    while len(que)>0:
        _,v = heapq.heappop(que)
        for u,c in g[v]:
            if d[v]+c[currency]>=d[u]:
                continue
            d[u] = d[v]+c[currency]
            heapq.heappush(que, (d[u], u))
    return d

yen_c = dijkstra(s,0)
snuuk_c = dijkstra(t,1)

res = [0]*n
res[n-1] = yen_c[n] + snuuk_c[n]
for i in range(n-2,-1,-1):
    res[i] = min(res[i+1], yen_c[i+1]+snuuk_c[i+1])

for r in res:
    print(10**15-r)

Solution (Python):
import heapq
N, M, s, t = map(int, input().split())
s, t = s - 1, t - 1
G_yen = [[] for i in range(N)]
G_snuuk = [[] for i in range(N)]
for i in range(M):
    u, v, a, b = map(int, input().split())
    u, v = u - 1, v - 1
    G_yen[u].append([v, a])
    G_yen[v].append([u, a])
    G_snuuk[u].append([v, b])
    G_snuuk[v].append([u, b])


def dijkstra(x, G):
    d = [float('inf')] * N
    d[x] = 0
    visited = {x}

    
    hq = [(0, x)]

    while hq:
        u = heapq.heappop(hq)[1]
        visited.add(u)

        for node, cost in G[u]:
            if (node not in visited) and d[node] > d[u] + cost:
                d[node] = d[u] + cost
                heapq.heappush(hq, (d[u]+cost, node))
    return d


d_yen = dijkstra(s, G_yen)
d_snuuk = dijkstra(t, G_snuuk)

ans = 10 ** 15
ans_list = []
for i in reversed(range(N)):
    ans = min(ans, d_yen[i] + d_snuuk[i])
    ans_list.append(10 ** 15 - ans)

print(*ans_list[::-1], sep='\n')

Solution (Python):

import heapq
n,m,s,t=map(int,input().split())
s,t=s-1,t-1
gy=[[]for i in range(n)]
gs=[[]for i in range(n)]
for i in range(m):
    u,v,a,b=map(int,input().split())
    u,v=u-1,v-1
    gy[u].append((a,v))
    gy[v].append((a,u))
    gs[u].append((b,v))
    gs[v].append((b,u))

d_y=[9999999999999999 for i in range(n)]
d_s=[9999999999999999 for i in range(n)]
h=[(0,s)]
while len(h):
    c,x=heapq.heappop(h)
    if c<d_y[x]:
        d_y[x]=c
    else:
        continue
    for i in range(len(gy[x])):
        if gy[x][i][0]+c<d_y[gy[x][i][1]]:
            heapq.heappush(h,(gy[x][i][0]+c,gy[x][i][1]))
h=[(0,t)]
while len(h):
    c,x=heapq.heappop(h)
    if c<d_s[x]:
        d_s[x]=c
    else:
        continue
    for i in range(len(gs[x])):
        if gs[x][i][0]+c<d_s[gs[x][i][1]]:
            heapq.heappush(h,(gs[x][i][0]+c,gs[x][i][1]))
ans=[0]
for i in range(n):
    ans.append(max(10**15-d_y[n-i-1]-d_s[n-i-1],ans[i]))
for i in range(n):
    print(ans[-i-1])

Solution (Python):
import heapq
N,M,S,T = map(int,input().split())
src = [tuple(map(int,input().split())) for i in range(M)]
S,T = S-1,T-1

INF = float('inf')
def dijkstra(is_yen):
    g = [[] for i in range(N)]
    for u,v,a,b in src:
        u,v = u-1,v-1
        c = a if is_yen else b
        g[u].append((v,c))
        g[v].append((u,c))
    costs = [INF] * N
    start = S if is_yen else T
    costs[start] = 0
    hq = [(0,start)]
    heapq.heapify(hq)
    while hq:
        _,v = heapq.heappop(hq)
        for to,c in g[v]:
            if costs[v]+c >= costs[to]: continue
            costs[to] = costs[v]+c
            heapq.heappush(hq, (costs[to],to))
    return costs

yens = dijkstra(1)
snuuks = dijkstra(0)

ans = [None] * N
ans[-1] = yens[-1] + snuuks[-1]
for i in reversed(range(N-1)):
    ans[i] = min(ans[i+1], yens[i]+snuuks[i])

for a in ans:
    print(10**15 - a)

Solution (Python):
import math, string, itertools, fractions, collections, re, array, bisect, sys, random, time, copy, functools
from heapq import heappush, heappop, heappushpop, heapify, heapreplace
input = sys.stdin.readline

N, M, S, T = [int(_) for _ in input().split()]
UVAB = [[int(_) for _ in input().split()] for _ in range(M)]
G1 = collections.defaultdict(lambda: collections.defaultdict(int))
G2 = collections.defaultdict(lambda: collections.defaultdict(int))

for u, v, a, b in UVAB:
    u -= 1
    v -= 1
    G1[u][v] = G1[v][u] = a
    G2[u][v] = G2[v][u] = b


def dijkstra(V, G, start):
    INF = float('inf')
    D = [INF for _ in range(V)]
    D[start] = 0
    H = [(0, start)]
    while H:
        du, u = heappop(H)
        if D[u] < du:
            continue
        for v, d in G[u].items():
            if D[v] > du + d:
                D[v] = du + d
                heappush(H, (D[v], v))
    return D


D1 = dijkstra(N, G1, S - 1)
D2 = dijkstra(N, G2, T - 1)

D = [10**15 - sum(_) for _ in zip(D1, D2)]
for i in range(N - 1, 0, -1):
    D[i - 1] = max(D[i - 1], D[i])
print(*D, sep='\n')

Solution (Python):
import math, string, itertools, fractions, collections, re, array, bisect, sys, random, time, copy, functools
from heapq import heappush, heappop, heappushpop, heapify, heapreplace


N, M, S, T = [int(_) for _ in input().split()]
UVAB = [[int(_) for _ in input().split()] for _ in range(M)]
G1 = collections.defaultdict(lambda: collections.defaultdict(int))
G2 = collections.defaultdict(lambda: collections.defaultdict(int))

for u, v, a, b in UVAB:
    u -= 1
    v -= 1
    G1[u][v] = G1[v][u] = a
    G2[u][v] = G2[v][u] = b


def dijkstra(V, G, start):
    INF = float('inf')
    D = [INF for _ in range(V)]
    D[start] = 0
    H = [(0, start)]
    while H:
        du, u = heappop(H)
        if D[u] < du:
            continue
        for v, d in G[u].items():
            if D[v] > du + d:
                D[v] = du + d
                heappush(H, (D[v], v))
    return D


D1 = dijkstra(N, G1, S - 1)
D2 = dijkstra(N, G2, T - 1)

D = [10**15 - sum(_) for _ in zip(D1, D2)]
for i in range(N - 1, 0, -1):
    D[i - 1] = max(D[i - 1], D[i])
print(*D, sep='\n')

Solution (Python):
import math, string, itertools, fractions, collections, re, array, bisect, sys, random, time, copy, functools
from heapq import heappush, heappop, heappushpop, heapify, heapreplace

N, M, S, T = [int(_) for _ in input().split()]
UVAB = [[int(_) for _ in input().split()] for _ in range(M)]
G1 = collections.defaultdict(lambda: collections.defaultdict(int))
G2 = collections.defaultdict(lambda: collections.defaultdict(int))

for u, v, a, b in UVAB:
    u -= 1
    v -= 1
    G1[u][v] = G1[v][u] = a
    G2[u][v] = G2[v][u] = b


def dijkstra(V, G, start):
    INF = float('inf')
    D = [INF for _ in range(V)]
    D[start] = 0
    H = [(0, start)]
    while H:
        du, u = heappop(H)
        if D[u] < du:
            continue
        for v, d in G[u].items():
            if D[v] > du + d:
                D[v] = du + d
                heappush(H, (D[v], v))
    return D


D1 = dijkstra(N, G1, S - 1)
D2 = dijkstra(N, G2, T - 1)

D = [10**15 - sum(_) for _ in zip(D1, D2)]
for i in range(N - 1, 0, -1):
    D[i - 1] = max(D[i - 1], D[i])
print(*D, sep='\n')

Solution (Python):
import math, string, itertools, fractions, collections, re, array, bisect, sys, random, time, copy, functools
from heapq import heappush, heappop, heappushpop, heapify, heapreplace


N, M, S, T = [int(_) for _ in input().split()]
UVAB = [[int(_) for _ in input().split()] for _ in range(M)]
G1 = collections.defaultdict(lambda: collections.defaultdict(int))
G2 = collections.defaultdict(lambda: collections.defaultdict(int))

for u, v, a, b in UVAB:
    u -= 1
    v -= 1
    G1[u][v] = G1[v][u] = a
    G2[u][v] = G2[v][u] = b


def dijkstra(V, G, start):
    INF = float('inf')
    D = [INF for _ in range(V)]
    D[start] = 0
    H = [(0, start)]
    while H:
        du, u = heappop(H)
        if D[u] < du:
            continue
        for v, d in G[u].items():
            if D[v] > du + d:
                D[v] = du + d
                heappush(H, (D[v], v))
    return D


D1 = dijkstra(N, G1, S - 1)
D2 = dijkstra(N, G2, T - 1)

D = [10**15 - sum(_) for _ in zip(D1, D2)]
for i in range(N - 1, 0, -1):
    D[i - 1] = max(D[i - 1], D[i])
print(*D, sep='\n')

Solution (Python):
import math, string, itertools, fractions, collections, re, array, bisect, sys, random, time, copy, functools
from heapq import heappush, heappop, heappushpop, heapify, heapreplace
input = sys.stdin.readline

N, M, S, T = [int(_) for _ in input().split()]
UVAB = [[int(_) for _ in input().split()] for _ in range(M)]
G1 = collections.defaultdict(lambda: collections.defaultdict(int))
G2 = collections.defaultdict(lambda: collections.defaultdict(int))

for u, v, a, b in UVAB:
    u -= 1
    v -= 1
    G1[u][v] = G1[v][u] = a
    G2[u][v] = G2[v][u] = b


def dijkstra(V, G, start):
    INF = float('inf')
    D = [INF for _ in range(V)]
    D[start] = 0
    H = [(0, start)]
    while H:
        du, u = heappop(H)
        if D[u] < du:
            continue
        for v, d in G[u].items():
            if D[v] > du + d:
                D[v] = du + d
                heappush(H, (D[v], v))
    return D


D1 = dijkstra(N, G1, S - 1)
D2 = dijkstra(N, G2, T - 1)

D = [10**15 - sum(_) for _ in zip(D1, D2)]
for i in range(N - 1, 0, -1):
    D[i - 1] = max(D[i - 1], D[i])
print(*D, sep='\n')

Solution (Python):
import heapq
from collections import defaultdict

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

graph_y = defaultdict(dict)
graph_s = defaultdict(dict)

for i in range(m):
	u, v, a, b = list(map(int, input().split()))
	graph_y[u - 1][v - 1] = a
	graph_y[v - 1][u - 1] = a
	graph_s[u - 1][v - 1] = b
	graph_s[v - 1][u - 1] = b

dist_node_ys = defaultdict(lambda: float("inf"))
dist_node_ys[s - 1] = 0

Q = []
heapq.heappush(Q, (dist_node_ys[s - 1], s - 1))

while Q: 
	dis, v = heapq.heappop(Q)
	if dist_node_ys[v] < dis:
		continue
	for i in graph_y[v]:
		u = i
		w = graph_y[v][i]
		alt = dis + w
		if dist_node_ys[u] > alt:
			dist_node_ys[u] = alt
			heapq.heappush(Q, (alt, u))


dist_node_st = defaultdict(lambda: float("inf"))
dist_node_st[t - 1] = 0

Q = []
heapq.heappush(Q, (dist_node_st[t - 1], t - 1))

while Q: 
	dis, v = heapq.heappop(Q)
	if dist_node_st[v] < dis:
		continue
	for i in graph_s[v]:
		u = i
		w = graph_s[v][i]
		alt = dis + w
		if dist_node_st[u] > alt:
			dist_node_st[u] = alt
			heapq.heappush(Q, (alt, u))

ansL = []
X = []
for i in range(n):
	heapq.heappush(X, dist_node_ys[n - 1 - i] + dist_node_st[n - 1 - i])
	ansL.append(X[0])

for i in range(1, n + 1):
	print(1000000000000000 - ansL[- i])

Solution (Python):
from heapq import heapify,heappop,heappush
N,M,s,t=map(int,input().split())
Graph1=[set() for i in range(N)]
Graph2=[set() for i in range(N)]
inf=float("inf")
for i in range(M):
  u,v,a,b=map(int,input().split())
  Graph1[u-1].add((a,v-1))
  Graph1[v-1].add((a,u-1))
  Graph2[u-1].add((b,v-1))
  Graph2[v-1].add((b,u-1))
  
def dijkstra(s,n,links):
  cost=[inf]*n
  visited=[False]*n
  cost[s]=0
  heap=[(0,s)]
  heapify(heap)
  while heap:
    hc,hp=heappop(heap)
    if not visited[hp]:
      visited[hp]=True
      for c,p in links[hp]:
        if not visited[p]:
          if c+hc<=cost[p]:
            cost[p]=c+hc
            heappush(heap,(cost[p],p))
  return cost
 
cost1=dijkstra(s-1,N,Graph1)
cost2=dijkstra(t-1,N,Graph2)

ans=[0]*N
a=inf
for i in range(N)[::-1]:
  a=min(a,cost1[i]+cost2[i])
  ans[i]=10**15-a
for i in ans:
  print(i)

Solution (Python):
import heapq
INF=10**15
class weighted_graph():
    Vertex= 1
    AdjList=[dict() for i in range(Vertex)]
    Edge=[]
    directed=False
    def __init__(self,size,directed=False):
        self.directed=directed
        self.Vertex=size
        self.AdjList=[dict() for i in range(self.Vertex)]
    def add_edge(self,start,finish,weight):
        self.AdjList[start][finish]=weight
        self.Edge.append((start,finish,weight))
        if not(self.directed):
            self.AdjList[finish][start]=weight
    def Dijkstra(self, st):
        dist=[INF for i in range(N)]
        dist[st]=0
        q=[]
        heapq.heappush(q,(0,st))
        while (len(q)!=0):
            prc,src=heapq.heappop(q)
            if dist[src]<prc:
                continue
            for dest in self.AdjList[src]:
                cost=self.AdjList[src][dest]
                if dist[dest]>dist[src]+cost:
                    dist[dest]=dist[src]+cost
                    heapq.heappush(q,(dist[dest],dest))                
        return dist
    def Warshall_Floyd(self):
        d=[[INF for i in range(self.Vertex)] for i in range(self.Vertex)]
        for seq in self.Edge:
            d[seq[0]][seq[1]]=seq[2]
            if not(self.directed):
                d[seq[1]][seq[0]]=seq[2]
        for k in range(self.Vertex):
            for i in range(self.Vertex):
                for j in range(self.Vertex):
                    if d[i][j]>d[i][k]+d[k][j]:
                        d[i][j]=d[i][k]+d[k][j]
        return d
N,M,s,t=map(int,input().split())
s-=1;t-=1
G=weighted_graph(N,directed=False)
H=weighted_graph(N,directed=False)
for _ in range(M):
    u,v,a,b=map(int,input().split())
    G.add_edge(u-1,v-1,a)
    H.add_edge(u-1,v-1,b)
dist1=G.Dijkstra(s)
dist2=H.Dijkstra(t)
tmp=[INF-dist1[i]-dist2[i] for i in range(N)]
ans=[0 for i in range(N)]
ans[-1]=tmp[-1]
for i in range(N-1)[::-1]:
    ans[i]=max(ans[i+1],tmp[i])
for i in ans:
    print(i)

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


def initialize(adj, s):
    MAX_NUM = float('inf')
    parent = {s: None}
    d = {vertex: MAX_NUM for vertex in adj.keys()}
    d[s] = 0
    return d, parent


def initialize_int(adj, s):
    """
    assume that all vertex in {0, 1, 2, ..., N - 1}
    """
    N = len(adj)
    MAX_NUM = float('inf')
    d = [MAX_NUM] * N
    d[s] = 0
    parent = [None] * N
    return d, parent







def dijkstra_simple(adj, w, s):
    d, parent = initialize_int(adj, s)
    priority_queue = []
    heappush(priority_queue, (d[s], s))
    while priority_queue:
        distance, source = heappop(priority_queue) 
        for neighbor in adj[source]:
            new_distance = distance + w[(source, neighbor)]
            if new_distance < d[neighbor]:
                d[neighbor] = new_distance
                parent[neighbor] = source
                heappush(priority_queue, (new_distance, neighbor))
    return d


n, m, s, t = [int(elem) for elem in fin().split()]
s -= 1
t -= 1
adj = [[] for _ in range(n)]
yen_weights = dict()
snuuk_weights = dict()
for _ in range(m):
    u, v, a, b = [int(elem) for elem in fin().split()]
    u -= 1
    v -= 1
    for v1, v2 in [(u, v), (v, u)]:
        adj[v1].append(v2)
        yen_weights[(v1, v2)] = a
        snuuk_weights[(v1, v2)] = b

d_yen = dijkstra_simple(adj, yen_weights, s)
d_snuuk = dijkstra_simple(adj, snuuk_weights, t)
min_cost = float('inf')
min_cost_after_each_year_reversed = []
for vertex in reversed(range(n)):
    min_cost = min(min_cost, d_yen[vertex] + d_snuuk[vertex])
    min_cost_after_each_year_reversed.append(min_cost)

initial_money = 10**15
for cost in reversed(min_cost_after_each_year_reversed):
    print(initial_money - cost)

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


def initialize(adj, s):
    MAX_NUM = float('inf')
    parent = {s: None}
    d = {vertex: MAX_NUM for vertex in adj.keys()}
    d[s] = 0
    return d, parent


def initialize_int(adj, s):
    """
    assume that all vertex in {0, 1, 2, ..., N - 1}
    """
    N = len(adj)
    MAX_NUM = float('inf')
    d = [MAX_NUM] * N
    d[s] = 0
    parent = [None] * N
    return d, parent







def dijkstra_simple(adj, w, s):
    d, parent = initialize_int(adj, s)
    priority_queue = []
    heappush(priority_queue, (d[s], s))
    while priority_queue:
        distance, source = heappop(priority_queue) 
        for neighbor in adj[source]:
            new_distance = distance + w[(source, neighbor)]
            if new_distance < d[neighbor]:
                d[neighbor] = new_distance
                parent[neighbor] = source
                heappush(priority_queue, (new_distance, neighbor))
    return d


n, m, s, t = [int(elem) for elem in fin().split()]
s -= 1
t -= 1
adj = [[] for _ in range(n)]
yen_weights = dict()
snuuk_weights = dict()
for _ in range(m):
    u, v, a, b = [int(elem) for elem in fin().split()]
    u -= 1
    v -= 1
    for v1, v2 in [(u, v), (v, u)]:
        adj[v1].append(v2)
        yen_weights[(v1, v2)] = a
        snuuk_weights[(v1, v2)] = b

d_yen = dijkstra_simple(adj, yen_weights, s)
d_snuuk = dijkstra_simple(adj, snuuk_weights, t)
min_cost = float('inf')
min_cost_after_each_year_reversed = []
for vertex in reversed(range(n)):
    min_cost = min(min_cost, d_yen[vertex] + d_snuuk[vertex])
    min_cost_after_each_year_reversed.append(min_cost)

initial_money = 10**15
for cost in reversed(min_cost_after_each_year_reversed):
    print(initial_money - cost)

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


def initialize(adj, s):
    MAX_NUM = float('inf')
    parent = {s: None}
    d = {vertex: MAX_NUM for vertex in adj.keys()}
    d[s] = 0
    return d, parent


def initialize_int(adj, s):
    """
    assume that all vertex in {0, 1, 2, ..., N - 1}
    """
    N = len(adj)
    MAX_NUM = float('inf')
    d = [MAX_NUM] * N
    d[s] = 0
    parent = [None] * N
    return d, parent







def dijkstra_simple(adj, w, s):
    d, parent = initialize_int(adj, s)
    priority_queue = []
    heappush(priority_queue, (d[s], s))
    while priority_queue:
        distance, source = heappop(priority_queue) 
        for neighbor in adj[source]:
            new_distance = distance + w[(source, neighbor)]
            if new_distance < d[neighbor]:
                d[neighbor] = new_distance
                parent[neighbor] = source
                heappush(priority_queue, (new_distance, neighbor))
    return d


n, m, s, t = [int(elem) for elem in fin().split()]
s -= 1
t -= 1
adj = defaultdict(list)
yen_weights = dict()
snuuk_weights = dict()
for _ in range(m):
    u, v, a, b = [int(elem) for elem in fin().split()]
    u -= 1
    v -= 1
    for v1, v2 in [(u, v), (v, u)]:
        adj[v1].append(v2)
        yen_weights[(v1, v2)] = a
        snuuk_weights[(v1, v2)] = b

d_yen = dijkstra_simple(adj, yen_weights, s)
d_snuuk = dijkstra_simple(adj, snuuk_weights, t)
min_cost = float('inf')
min_cost_after_each_year_reversed = []
for vertex in reversed(range(n)):
    min_cost = min(min_cost, d_yen[vertex] + d_snuuk[vertex])
    min_cost_after_each_year_reversed.append(min_cost)

initial_money = 10**15
for cost in reversed(min_cost_after_each_year_reversed):
    print(initial_money - cost)

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


def initialize(adj, s):
    MAX_NUM = float('inf')
    parent = {s: None}
    d = {vertex: MAX_NUM for vertex in adj.keys()}
    d[s] = 0
    return d, parent


def initialize_int(adj, s):
    """
    assume that all vertex in {0, 1, 2, ..., N - 1}
    """
    N = len(adj)
    MAX_NUM = float('inf')
    d = [MAX_NUM] * N
    d[s] = 0
    parent = [None] * N
    return d, parent







def dijkstra_simple(adj, w, s):
    d, parent = initialize_int(adj, s)
    priority_queue = []
    heappush(priority_queue, (d[s], s))
    while priority_queue:
        distance, source = heappop(priority_queue) 
        for neighbor in adj[source]:
            new_distance = distance + w[(source, neighbor)]
            if new_distance < d[neighbor]:
                d[neighbor] = new_distance
                parent[neighbor] = source
                heappush(priority_queue, (new_distance, neighbor))
    return d


n, m, s, t = [int(elem) for elem in fin().split()]
s -= 1
t -= 1
adj = defaultdict(list)
yen_weights = dict()
snuuk_weights = dict()
for _ in range(m):
    u, v, a, b = [int(elem) for elem in fin().split()]
    u -= 1
    v -= 1
    for v1, v2 in [(u, v), (v, u)]:
        adj[v1].append(v2)
        yen_weights[(v1, v2)] = a
        snuuk_weights[(v1, v2)] = b

d_yen = dijkstra_simple(adj, yen_weights, s)
d_snuuk = dijkstra_simple(adj, snuuk_weights, t)
min_cost = float('inf')
min_cost_after_each_year_reversed = []
for vertex in reversed(range(n)):
    min_cost = min(min_cost, d_yen[vertex] + d_snuuk[vertex])
    min_cost_after_each_year_reversed.append(min_cost)

initial_money = 10**15
for cost in reversed(min_cost_after_each_year_reversed):
    print(initial_money - cost)