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



Sample input:
4 3 2 3
1 4 1 100
1 2 1 10
1 3 20 1


Sample output:
999999999999998
999999999999989
999999999999979
999999999999897

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import sys
from heapq import heappop, heappush
from itertools import accumulate


def dijkstra(n, edges, start, *, adj_matrix=False, default_value=float('inf')):

    inf = float('inf')
    costs = [inf] * n
    costs[start] = 0
    pq, rem = [(0, start)], n - 1

    while pq and rem:
        tmp_cost, tmp_node = heappop(pq)
        if costs[tmp_node] < tmp_cost:
            continue
        rem -= 1

        nxt_edges = ((node, cost) for node, cost in enumerate(edges[tmp_node]) if cost != default_value) \
                    if adj_matrix else edges[tmp_node]

        for nxt_node, nxt_cost in nxt_edges:
            new_cost = tmp_cost + nxt_cost
            if costs[nxt_node] > new_cost:
                costs[nxt_node] = new_cost
                heappush(pq, (new_cost, nxt_node))

    return costs


# n, m, s, t = map(int, input().split())
# trains = [list(map(int, l.strip().split())) for l in sys.stdin.readlines()]

# yen_edges = [[float('inf') if __ != _ else 0 for __ in range(n)]
#              for _ in range(n)]
# snuke_edges = [[float('inf') if __ != _ else 0 for __ in range(n)]
#                for _ in range(n)]
# for i, j, yen, snuke in trains:
#     yen_edges[i - 1][j - 1] = yen
#     yen_edges[j - 1][i - 1] = yen
#     snuke_edges[i - 1][j - 1] = snuke
#     snuke_edges[j - 1][i - 1] = snuke

# yen_cost = dijkstra(n, yen_edges, s - 1, adj_matrix=True)
# snuke_cost = dijkstra(n, snuke_edges, t - 1, adj_matrix=True)
# costs = [yen + snuke for yen, snuke in zip(yen_cost, snuke_cost)]

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

yen_edges = [[] for _ in range(n)]
snuke_edges = [[] for _ in range(n)]
for l in sys.stdin.readlines():
    u, v, yen, snuke = map(int, l.strip().split())
# for _ in range(m):
#     u, v, yen, snuke = map(int, input().split())
    yen_edges[u - 1].append((v - 1, yen))
    yen_edges[v - 1].append((u - 1, yen))
    snuke_edges[u - 1].append((v - 1, snuke))
    snuke_edges[v - 1].append((u - 1, snuke))

yen_costs = dijkstra(n, yen_edges, s - 1)
snuke_costs = dijkstra(n, snuke_edges, t - 1)

final_costs = list(accumulate([yen + snuke for yen, snuke in zip(yen_costs, snuke_costs)][::-1], min))[::-1]
asset = 10**15
for final_cost in final_costs:
    print(asset - final_cost)

Submission status: Accepted

Solution code:
import heapq as hq
from collections import deque
n,m,s,t=map(int,input().split())
#リンク情報をつくる
yenLinks={}
snkLinks={}
for _ in range(m):
    u,v,a,b=map(int,input().split())
    if u not in yenLinks:
        yenLinks[u]=[(v,a)]
        snkLinks[u]=[(v,b)]
    else:
        yenLinks[u].append((v,a))
        snkLinks[u].append((v,b))
    if v not in yenLinks:
        yenLinks[v]=[(u,a)]
        snkLinks[v]=[(u,b)]
    else:
        yenLinks[v].append((u,a))
        snkLinks[v].append((u,b))
#Dijkstra法をする関数
INF=float('inf')
def dijkstra(start,links,nodeNum):
    ans=[INF for _ in range(nodeNum+1)]
    ans[start]=0
    PQ=[(0,start)]
    hq.heapify(PQ)
    while PQ:
        (Vd,V) = hq.heappop(PQ)
        #print([V,Vd,ans[V]])
        if Vd > ans[V]:
            continue
        for (W,D) in links[V]:
            cand = ans[V] + D
            if cand < ans[W]:
                ans[W] = cand
                hq.heappush(PQ,(ans[W],W))
            #print(PQ)
    return(ans)
#Dijkstra法実行
yenKstra=dijkstra(s,yenLinks,n)
snkKstra=dijkstra(t,snkLinks,n)
#答えを求める
i=n
ans=INF
answers=deque()
while i>0:
    cand = yenKstra[i]+snkKstra[i]
    ans = min(ans,cand)
    answers.append(10**15-ans)
    i-=1
#出力
for _ in range(n):
    print(answers.pop())

Submission status: Accepted

Solution code:
import heapq as hq
from collections import deque
n,m,s,t=map(int,input().split())
#リンク情報をつくる
yenLinks={}
snkLinks={}
for _ in range(m):
    u,v,a,b=map(int,input().split())
    if u not in yenLinks:
        yenLinks[u]=[(v,a)]
        snkLinks[u]=[(v,b)]
    else:
        yenLinks[u].append((v,a))
        snkLinks[u].append((v,b))
    if v not in yenLinks:
        yenLinks[v]=[(u,a)]
        snkLinks[v]=[(u,b)]
    else:
        yenLinks[v].append((u,a))
        snkLinks[v].append((u,b))
#Dijkstra法をする関数
INF=float('inf')
def dijkstra(start,links,nodeNum):
    ans=[INF for _ in range(nodeNum+1)]
    ans[start]=0
    PQ=[(0,start)]
    hq.heapify(PQ)
    while PQ:
        (Vd,V) = hq.heappop(PQ)
        #print([V,Vd,ans[V]])
        if Vd > ans[V]:
            continue
        for (W,D) in links[V]:
            cand = ans[V] + D
            if cand < ans[W]:
                ans[W] = cand
                hq.heappush(PQ,(ans[W],W))
            #print(PQ)
    return(ans)
#Dijkstra法実行
yenKstra=dijkstra(s,yenLinks,n)
snkKstra=dijkstra(t,snkLinks,n)
#答えを求める
i=n
ans=INF
answers=[]
while i>0:
    cand = yenKstra[i]+snkKstra[i]
    ans = min(ans,cand)
    answers.append(10**15-ans)
    i-=1
answers.reverse()
#出力
for ans in answers:
    print(ans)

Submission status: Accepted

Solution code:
import heapq
n,m,s,t=list(map(int, input().strip().split()))
links_y=[[]for i in range(n) ]
links_s=[[]for i in range(n) ]
INF=float('inf')
for i in range(m):
    u,v,a,b=list(map(int, input().strip().split()))
    links_y[u-1].append((v-1,a))
    links_y[v-1].append((u-1,a))
    links_s[u-1].append((v-1,b))
    links_s[v-1].append((u-1,b))

def dijkstra(frm, links):
    dist=[INF]*n
    dist[frm]=0
    Q=[(0,frm)]
    heapq.heapify(Q)
    while Q:
        d,u = heapq.heappop(Q)
        for v,dd in links[u]:
            if dist[v]> d+dd:
                dist[v]=dd+d
                heapq.heappush(Q,(dist[v],v))
    return dist
yen_cost=dijkstra(s-1,links_y)
snk_cost=dijkstra(t-1,links_s)
sumyensnk=[i+j for i,j in zip(yen_cost,snk_cost)]
min_snk=[INF]*n
tmp=INF
for i in range(n)[::-1]:
    min_snk[i] = min(sumyensnk[i],tmp)
    tmp = min_snk[i]
money=10**15
for sumsnk in min_snk:
    print(money-sumsnk)

Submission status: Accepted

Solution code:
import heapq

n,m,s,t=map(int,input().split())
TRAIN=[None]*m

for i in range(m):
    TRAIN[i]=list(map(int,input().split()))


YEN=[10**16]*(n+1)#sから国iまで行くときの最小円
SNOOK=[10**16]*(n+1)#国iからtまで行くときの最小スヌーク
YEN[s]=0
SNOOK[t]=0


TRAINMAP=[[] for i in range(n+1)]

for i in range(m):
    TRAINMAP[TRAIN[i][0]]+=[(TRAIN[i][1],TRAIN[i][2],TRAIN[i][3])]
    TRAINMAP[TRAIN[i][1]]+=[(TRAIN[i][0],TRAIN[i][2],TRAIN[i][3])]



checking=[(0,s)]

while checking:

    cost,checktown=heapq.heappop(checking)
    
    for i in TRAINMAP[checktown]:
        if YEN[i[0]]>cost+i[1]:
            YEN[i[0]]=cost+i[1]
            heapq.heappush(checking,(cost+i[1],i[0]))

checking=[(0,t)]

while checking:

    cost,checktown=heapq.heappop(checking)
   
    for i in TRAINMAP[checktown]:
        if SNOOK[i[0]]>cost+i[2]:
            SNOOK[i[0]]=cost+i[2]
            heapq.heappush(checking,(cost+i[2],i[0]))



MONEY=[10**16]*(n+1)
MONEY[n]=YEN[n]+SNOOK[n]

for i in range(n-1,0,-1):
    if YEN[i]+SNOOK[i]<MONEY[i+1]:
        MONEY[i]=YEN[i]+SNOOK[i]
    else:
        MONEY[i]=MONEY[i+1]


for i in range(1,n+1):
    print(10**15-MONEY[i])

Submission status: Accepted

Solution code:
import heapq
# dijkstra
# edges = |V|のリスト
# 頂点iから頂点jにコストwで移動可能な場合：edges[i] = [(j, w)]

def dijkstra(n, edges, start):
    INF = float('inf')
    vertices = [INF] * n # 初期化
    vertices[start] = 0 # スタートの距離はゼロ
    hq = [(0, start)]
    heapq.heapify(hq)

    while hq:
        cost, v = heapq.heappop(hq)
        
        for to, w in edges[v]:
            if cost + w >= vertices[to]:
                continue
            vertices[to] = cost + w
            heapq.heappush(hq, (vertices[to], to))
    
    return vertices

# input
n, m, s, t = map(int, input().split())
G = [list(map(int, input().split())) for _ in range(m)]
INF = float('inf')


G_yen = [[] for _ in range(n)]
G_snu = [[] for _ in range(n)]

s, t = s - 1, t - 1

for u, v, a, b in G:
    G_yen[u - 1].append((v - 1, a))
    G_yen[v - 1].append((u - 1, a))
    G_snu[u - 1].append((v - 1, b))
    G_snu[v - 1].append((u - 1, b))

yen = dijkstra(n, G_yen, s)
snu = dijkstra(n, G_snu, t)

ans = [INF]

for i in reversed(range(n)):
    tmp = snu[i] + yen[i]
    ans.append(min(ans[-1], tmp))

for i in reversed(ans[1:]):
    print(10 ** 15 - i)

Submission status: Accepted

Solution code:
from collections import defaultdict
from heapq import heappop, heappush

n, m, s, t = map(int, input().split())
c = 10**15
graph = defaultdict(list)
for _ in range(m):
  u, v, a, b = map(int, input().split())
  graph[u].append((v, a, b))
  graph[v].append((u, a, b))

dyen = defaultdict(lambda:float("INF"))
dsnuuk = defaultdict(lambda:float("INF"))
dyen[s] = 0
dsnuuk[t] = 0

def dijkstra(s, m):
  used = defaultdict(bool)
  q = []
  heappush(q, (0, s))

  while len(q):
    v = heappop(q)
    cost, cur = v[0], v[1]

    if used[v]:
      continue
    used[v]=True

    for to, a, b in graph[cur]:
      if m==0 and dyen[to]>cost+a:
        dyen[to] = cost+a
        heappush(q, (cost+a, to))
      elif m==1 and dsnuuk[to]>cost+b:
        dsnuuk[to] = cost+b
        heappush(q, (cost+b, to))

dijkstra(s, 0)
dijkstra(t, 1)

costs = [float("INF")]*(n+1)
min_ = float("INF")
for i in range(n, 0, -1):
  min_ = min(min_, dyen[i]+dsnuuk[i])
  costs[i] = min_

for i in range(1, n+1):
  print(c-costs[i])

Submission status: Accepted

Solution code:
# coding: utf-8

import heapq

def dj(adjm, sn, start):
    n = len(adjm)
    d = [float("inf")] * n
    d[start] = 0
    q = []
    heapq.heappush(q, (0, start))

    while(q):
        td, v = heapq.heappop(q)
        for k in adjm[v].keys():
            nd = td + adjm[v][k][sn]
            if d[k] > nd:
                d[k] = nd
                heapq.heappush(q, (nd, k))
    return d


def main():
    N, M, S, T = map(int, input().split(" "))
    S -= 1
    T -= 1
    adjm = [{} for _ in range(N)]
    for i in range(M):
        u, v, a, b = map(int, input().split(" "))
        u -= 1
        v -= 1
        adjm[u][v] = adjm[v][u] = (a, b)
    cy = dj(adjm, 0, S)
    cs = dj(adjm, 1, T)
    cl = [(cy[i] + cs[i], i) for i in range(N)]
    heapq.heapify(cl)

    ic = int(1e15)
    c, y = heapq.heappop(cl)
    for i in range(N):
        while y < i:
            c, y = heapq.heappop(cl)
        print(ic-c)


if __name__ == "__main__":
    main()

Submission status: Accepted

Solution code:
from heapq import heappush, heappop
from collections import defaultdict

n, m, s, t = map(int, input().split())
y = 10**15


class Graph(object):
    def __init__(self):
        self.graph = defaultdict(list)

    def add_edge(self, src, dst, weight=1):
        self.graph[src].append((dst, weight))


class Dijkstra(object):
    def __init__(self, graph, start):
        self.g = graph.graph

        self.dist = defaultdict(lambda: float('inf'))
        self.dist[start] = 0

        self.Q = []
        heappush(self.Q, (self.dist[start], start))

        while self.Q:
            dist_u, u = heappop(self.Q)
            if self.dist[u] < dist_u:
                continue
            for v, weight in self.g[u]:
                alt = dist_u + weight
                if self.dist[v] > alt:
                    self.dist[v] = alt
                    heappush(self.Q, (alt, v))


yen_g = Graph()
sno_g = Graph()
for _ in range(m):
    u, v, a, b = map(int, input().split())
    yen_g.add_edge(u, v, a)
    yen_g.add_edge(v, u, a)
    sno_g.add_edge(u, v, b)
    sno_g.add_edge(v, u, b)

cost = [0] * n
yen_d = Dijkstra(yen_g, s)
sno_d = Dijkstra(sno_g, t)
for i in range(1, n + 1):
    cost[i - 1] = y - (yen_d.dist[i] + sno_d.dist[i])

ans = [y] * n
ans[n - 1] = cost[n - 1]
for i in range(n - 2, -1, -1):
    ans[i] = max(ans[i + 1], cost[i])

for a in ans:
    print(a)

Submission status: Accepted

Solution code:
from heapq import heappush, heappop

N, M, Start, Goal = map(int, input().split())
Start -= 1
Goal -= 1
adj_list = [[] for _ in range(N)]
for i in range(M):
  u, v, yen, sunuke = map(int, input().split())
  u -= 1
  v -= 1
  adj_list[u].append([u, v, yen, sunuke])
  adj_list[v].append([v, u, yen, sunuke])

def dijkstra(start, changed):
  res = [ -1 for _ in range(N) ]
  q = [[0, start]]
  visited = {}

  while len(q)>0:
    money, city = heappop(q)
    if res[city]>=0:
      continue
    res[city] = money

    for from_city, to_city, yen, sunuke  in adj_list[city]:
      if res[to_city]<0:
        cost = sunuke if changed else yen
        heappush(q, [money+[yen, sunuke][changed], to_city])
        

  return res


min_yen_path = dijkstra(Start, 0)
min_sunuke_path = dijkstra(Goal, 1)

res = []
max_sunuke = 0
for i in reversed(range(N)):
  s = 10**15-min_yen_path[i]-min_sunuke_path[i]
  max_sunuke = max([s, max_sunuke]) 
  res.append(max_sunuke)
  
for i in reversed(res):
  print(i)

Submission status: Accepted

Solution code:
from collections import defaultdict
import heapq
n,m,s,t =list(map(int,input().split()))

uvab =  [list(map(int,input().split())) for _ in range(m)]
en = [[] for _ in range(n) ]
snuke = [[] for _ in range(n)]

 
for u,v,a,b in uvab:
    u=u-1
    v=v-1
    en[u].append((a,v))
    en[v].append((a,u))
    snuke[u].append((b,v))
    snuke[v].append((b,u))
 
 
def dijkstra(edges, s):
    INF = 10 ** 15
    d = [INF for x in range(n)]
    d[s] = 0
    que = []
    heapq.heappush(que, (0,s))
 
    while len(que) > 0:
        u_d,u = heapq.heappop(que)
        if d[u] < u_d:
            continue
        for  v_d,v in edges[u]:
            if d[v] > d[u] + v_d:
                d[v] = d[u] + v_d
                heapq.heappush(que,(d[v],v))
    return d

en_ds =  dijkstra(en,s-1)
snuke_ds = dijkstra(snuke,t-1)
scores = [0] * n
for i in range(n):
  scores[i] = 10**15 - (en_ds[i] + snuke_ds[i])

ans = [ 10 ** 15 for _ in range(n)]
ans[n-1] = scores[n-1]
for i in range(n-2,-1,-1):
    ans[i] = max(ans[i+1],scores[i])
for a in ans:
    print(a)

Submission status: Accepted

Solution code:
import heapq
from collections import defaultdict
def gijkstra(n,E,s=1):
    d = [float('inf')]*(n+1)
    p = [-1]*(n+1)
    hq = [(0,s)]
    d[s] = 0
    while hq:
        u = heapq.heappop(hq)[1]
        for v, c in E[u]:
            if d[v] > d[u] + c:
                d[v], p[v] = d[u]+c, u
                heapq.heappush(hq, (d[u]+c, v))
    return d, p

n, m, s, t =  map(int,input().split())
E1 = defaultdict(set)
E2 = defaultdict(set)

for i in range(m):
    u,v,a,b = tuple(map(int,input().split()))
    E1[u].add((v,a))
    E1[v].add((u,a))
    E2[u].add((v,b))
    E2[v].add((u,b))
d1, _ = gijkstra(n,E1,s=s)
d2, _ = gijkstra(n,E2,s=t)
d = [d1[-1] + d2[-1],]
for i in range(n-1,0,-1):
    d.append(min(d[-1],d1[i]+d2[i]))
[print(10**15-c) for c in reversed(d)]

Submission status: Accepted

Solution code:
import heapq
initial = 10 ** 15

def di(link_costs, s):
    costs = [initial] * n
    costs[s] = 0
    node_list = []
    serched_node = set()
    heapq.heappush(node_list, (0, s))
    
    while(len(node_list) != 0 and len(serched_node) != n):
        index = heapq.heappop(node_list)[1]
        if index in serched_node:
            continue
        serched_node.add(index)
        link = links[index]
        for j in link:
            if j in serched_node:
                continue
        
            cost = link_costs[index][j]
            newcost =  costs[index] + cost
            if newcost < costs[j]:
                costs[j] = newcost
                heapq.heappush(node_list, (newcost, j))
    return costs
    
n, m, s, t  = list(map(int, input().split()))
s -= 1
t -= 1
links = [set() for _ in range(n)]
links_cost_en = [{} for __ in range(n)]
links_cost_sn = [{} for __ in range(n)]

for _ in range(m):
    u, v, a, b  = list(map(int, input().split()))
    links[u-1].add(v-1)
    links[v-1].add(u-1)
    links_cost_en[u - 1][v - 1] = a
    links_cost_en[v - 1][u - 1] = a
    links_cost_sn[u - 1][v - 1] = b
    links_cost_sn[v - 1][u - 1] = b

cost_en_from_s = di(links_cost_en, s)
cost_sn_to_t = di(links_cost_sn, t)
cost_list = [cost_en_from_s[i] + cost_sn_to_t[i] for i in range(n)]
 
ans = [initial] * n
ans[-1] = cost_list[-1]
for i in list(range(n - 1))[::-1]:
    ans[i] = min(ans[i + 1], cost_list[i])
for i in range(n):
    print(initial - ans[i])

Submission status: Accepted

Solution code:
import heapq
initial_cost = 10 ** 9
initial = 10 ** 15

def di(link_costs, s):
    costs = [initial] * n
    costs[s] = 0
    q = []
    heapq.heappush(q, (0, s))
    
    while(len(q) != 0):
        index_cost, index = heapq.heappop(q)
        if costs[index] < index_cost:
            continue

        for j in link_costs[index]:
            newcost = costs[index] + link_costs[index][j]
            if newcost < costs[j]:
                costs[j] = newcost
                heapq.heappush(q, (newcost, j))
    return costs
    
n, m, s, t  = list(map(int, input().split()))
s -= 1
t -= 1
links_cost_en = [{} for _ in range(n)]
links_cost_sn = [{} for _ in range(n)]

for _ in range(m):
    u, v, a, b  = list(map(int, input().split()))
    u -= 1
    v -= 1
    links_cost_en[u][v] = a
    links_cost_en[v][u] = a
    links_cost_sn[u][v] = b
    links_cost_sn[v][u] = b

cost_en_from_s = di(links_cost_en, s)
cost_sn_to_t = di(links_cost_sn, t)
cost_list = [cost_en_from_s[i] + cost_sn_to_t[i] for i in range(n)]

ans = [initial] * n
ans[-1] = cost_list[-1]
for i in list(range(n - 1))[::-1]:
    ans[i] = min(ans[i + 1], cost_list[i])
for i in range(n):
    print(initial - ans[i])

Submission status: Accepted

Solution code:
from heapq import heappush,heappop
N,M,s,t=map(int,input().split())
table=[[] for i in range(N)]
rtable=[[] for i in range(N)]
for i in range(M):
    u,v,a,b=map(int,input().split())
    table[u-1].append((a,v-1))
    table[v-1].append((a,u-1))
    rtable[u-1].append((b,v-1))
    rtable[v-1].append((b,u-1))
dij=[]
heappush(dij,(0,s-1))
val=[10**16]*N
val[s-1]=0
while dij:
    q,x=heappop(dij)
    if val[x]<q:
        continue
    for d,y in table[x]:
        if val[y]>val[x]+d:
            val[y]=val[x]+d
            heappush(dij,(val[y],y))
rdij=[]
heappush(rdij,(0,t-1))
rval=[10**16]*N
rval[t-1]=0
while rdij:
    q,x=heappop(rdij)
    if rval[x]<q:
        continue
    for d,y in rtable[x]:
        if rval[y]>rval[x]+d:
            rval[y]=rval[x]+d
            heappush(rdij,(rval[y],y))
ans=[]
t=val[N-1]+rval[N-1]
mod=pow(10,15)
ans.append(mod-t)
for i in range(N-2,-1,-1):
    t=min(t,val[i]+rval[i])
    ans.append(mod-t)
ans=ans[::-1]
for a in ans:
    print(a)

Submission status: Accepted

Solution code:
from heapq import heappush,heappop
from sys import setrecursionlimit
setrecursionlimit(10**6)
N,M,s,t=map(int,input().split())
table=[[] for i in range(N)]
rtable=[[] for i in range(N)]
for i in range(M):
    u,v,a,b=map(int,input().split())
    u,v=u-1,v-1
    table[u].append((a,v))
    table[v].append((a,u))
    rtable[u].append((b,v))
    rtable[v].append((b,u))
mod=pow(10,15)
def dijk(s,table):
    dij=[]
    heappush(dij,(0,s))
    val=[mod]*N
    val[s]=0
    while len(dij)>0:
        q,x=heappop(dij)
        if val[x]<q:
            continue
        for d,y in table[x]:
            if val[y]>val[x]+d:
                val[y]=val[x]+d
                heappush(dij,(val[y],y))
    return val
val=dijk(s-1,table)
rval=dijk(t-1,rtable)
score=[0]*N
for i in range(N):
    score[i]=mod-(val[i]+rval[i])
amax=[mod]*N
amax[-1]=score[-1]
for i in range(N-2,-1,-1):
    amax[i]=max(amax[i+1],score[i])
for i in range(N):
    print(amax[i])

Submission status: Accepted

Solution code:
import heapq
from collections import defaultdict

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

V=defaultdict(set)
V2=defaultdict(set)
for i in range(m):
  a,b,c,d=map(int,input().split())
  V[a-1].add((b-1,c))
  V[b-1].add((a-1,c))
  V2[a-1].add((b-1,d))
  V2[b-1].add((a-1,d))

def dijkstra(n,v,dedic):
  d=[float('inf')]*n
  d[v]=0
  
  hq=[(0,v)]
  
  while hq:
    u = heapq.heappop(hq)[1]
    for nv,c in dedic[u]:
      if d[nv]>d[u]+c:
        d[nv]=d[u]+c
        heapq.heappush(hq,(d[u]+c,nv))
        
  return d

ans=dijkstra(N,s-1,V)
ans2=dijkstra(N,t-1,V2)
ans3=[10**15 for i in range(N)]
ans3[N-1]=ans[N-1]+ans2[N-1]
for i in range(N-2,-1,-1):
  ans3[i]=min(ans3[i],ans3[i+1],ans[i]+ans2[i])

for i in range(N):
  print(10**15-ans3[i])

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import bisect
import heapq
import math
import random
import sys
from collections import Counter, defaultdict
from decimal import ROUND_CEILING, ROUND_HALF_UP, Decimal
from functools import lru_cache, reduce
from itertools import combinations, combinations_with_replacement, product, permutations

sys.setrecursionlimit(10000)


def read_int():
    return int(input())


def read_int_n():
    return list(map(int, input().split()))


def read_float():
    return float(input())


def read_float_n():
    return list(map(float, input().split()))


def read_str():
    return input()


def read_str_n():
    return list(map(str, input().split()))


def error_print(*args):
    print(*args, file=sys.stderr)


def mt(f):
    import time

    def wrap(*args, **kwargs):
        s = time.time()
        ret = f(*args, **kwargs)
        e = time.time()

        error_print(e - s, 'sec')
        return ret

    return wrap


@mt
def slv(n, m, s, t, UVAB):
    g = defaultdict(list)
    for u, v, a, b in UVAB:
        g[u].append((v, (a, b)))
        g[v].append((u, (a, b)))

    def d(s, ck):
        dist = [0 if s == i else sys.maxsize for i in range(n+1)]
        # p = [None for i in range(n+1)]
        q =[]
        heapq.heappush(q, (dist[s], s))
        while q:
            c, u = heapq.heappop(q)
            if dist[u] > c:
                continue
            for v, cost in g[u]:
                alt = dist[u] + cost[ck]
                if dist[v] > alt:
                    dist[v] = alt
                    heapq.heappush(q, (alt, v))
        return dist

    dist0 = d(s, 0)
    dist1 = d(t, 1)

    ans = [sys.maxsize] * (n+1)
    
    for i in range(n-1, -1, -1):
        # print(i)
        ans[i] = min(ans[i+1], dist1[i+1] + dist0[i+1])
    c = 10**15
    return '\n'.join(map(lambda x: str(c-x), ans[:-1]))


def main():
    n, m, s, t = read_int_n()
    UVAB = [read_int_n() for _ in range(m)]

    
    print(slv(n, m, s, t, UVAB))


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
N,M,S,T = map(int,input().split())
yX = [[] for _ in range(N)]
sX = [[] for _ in range(N)]
for i in range(M):
    u,v,a,b = map(int,input().split())
    yX[u-1].append((v-1,a))
    yX[v-1].append((u-1,a))
    sX[u-1].append((v-1,b))
    sX[v-1].append((u-1,b))

# 0-indexed
S,T = S-1,T-1

# ---------- ---------- ---------- ---------- ---------- ----------
# dijkstra's algorithm
# ---------- ---------- ---------- ---------- ---------- ----------
import heapq
INF = float("inf")
def dijkstra(start, dM, cost):
    hq = [(0,start)]
    heapq.heapify(hq)
    while hq:
        c, v = heapq.heappop(hq)
        for xto, xc in dM[v]:
            if c + xc >= cost[xto]:
                continue
            cost[xto] = c + xc
            heapq.heappush(hq, (cost[xto],xto))

# 頂点数
dN = N
# 開始頂点
start = S
# 隣接リスト (v,cost)
dM = yX
# コスト
cost1 = [INF]*dN
cost1[start] = 0
# 実行
dijkstra(start, dM, cost1)


# 開始頂点
start = T
# 隣接リスト (v,cost)
dM = sX
# コスト
cost2 = [INF]*dN
cost2[start] = 0
# 実行
dijkstra(start, dM, cost2)

Ans = [INF]
for i in reversed(range(N)):
    Ans.append(min(Ans[-1], cost1[i]+cost2[i]))

for ans in reversed(Ans[1:]):
    print(10**15 - ans)

Submission status: Accepted

Solution code:
from collections import defaultdict 
import sys
import heapq

sys.setrecursionlimit(10**8)

#N:頂点数   M:辺数
N,M,s,t = map(int,input().split())


#root[n] -> nからいけるlist
roots = defaultdict(set)

#weight[a] = start -> a のコスト 未探索->-1
weight_yen = [-1 for i in range(N+1)]
weight_snu = [-1 for i in range(N+1)]
weight_yen[s] = 0
weight_snu[t] = 0


for i in range(M):
	u,v,a,b = list(map(int,input().split())) #

	roots[u].add((v,a,b))
	roots[v].add((u,a,b))
		
	
def search_yen (n,w_0): #nから更新 w_0:確定コスト
	global weight_yen
		
	for root in list(roots[n]):
		i = root[0]
		w = w_0 + root[1]
		if weight_yen[i] == -1 or weight_yen[i] > w: #未探索orより小さい
			heapq.heappush(q, [w,i])
			weight_yen[i] = w
			
def search_snu (n,w_0): #nから更新 w_0:確定コスト
	global weight_snu
		
	for root in list(roots[n]):
		i = root[0]
		w = w_0 + root[2]
		if weight_snu[i] == -1 or weight_snu[i] > w: #未探索orより小さい
			heapq.heappush(q, [w,i])
			weight_snu[i] = w

#q = 次に探索する(確定する)もの q[0]=[w,n]
q = [[0,s]]
heapq.heapify(q)
			
while q:
	w,n = heapq.heappop(q)
	search_yen(n,w)
	
heapq.heappush(q, [0,t])
	
while q:
	w,n = heapq.heappop(q)
	search_snu(n,w)
	

finalans = float('inf')
ans_li = []

for i in range(0,N):
	ans = weight_yen[N-i] + weight_snu[N-i]
	finalans = min(finalans, ans)
	ans_li.append(finalans)
	
for i in range(N):
	print(10**15 - ans_li[N-i-1])

Submission status: Accepted

Solution code:
#参考URL:http://lethe2211.hatenablog.com/entry/2014/12/30/011030
import heapq
n,m,s,t=map(int,input().split())
s-=1
t-=1
Gyen=[dict() for i in range(n)]
Gsnu=[dict() for i in range(n)]
for i in range(m):
    u,v,a,b=map(int,input().split())
    u-=1
    v-=1
    Gyen[u][v]=a
    Gyen[v][u]=a
    Gsnu[u][v]=b
    Gsnu[v][u]=b
def dijkstra(adj, start):
    num = n          # グラフのノード数
    dist = [10**15 for i in range(num)] # 始点から各頂点までの最短距離を格納する
   
    dist[start] = 0
    q = []                  # プライオリティキュー．各要素は，(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル
    heapq.heappush(q, (0, start)) # 始点をpush
    while (len(q) != 0):
        prov_cost, src = heapq.heappop(q) # pop
        # プライオリティキューに格納されている最短距離が，現在計算できている最短距離より大きければ，distの更新をする必要はない
        if dist[src] < prov_cost:
            continue
        # 他の頂点の探索
        for dest in adj[src]:
            cost = adj[src][dest]
            if dist[dest] > dist[src] + cost:
                dist[dest] = dist[src] + cost # distの更新
                heapq.heappush(q, (dist[dest], dest)) # キューに新たな仮の距離の情報をpush                  
    return dist
CostYen=dijkstra(Gyen,s)
CostSnu=dijkstra(Gsnu,t)
Cost=[0 for i in range(n)]
for i in range(n):
    Cost[i]=CostYen[i]+CostSnu[i]
ans=[0 for i in range(n)]
ans[-1]=Cost[-1]
for i in list(range(n-1))[::-1]:
    ans[i]=min(ans[i+1],Cost[i])
for i in range(n):
    print(10**15-ans[i])

Submission status: Accepted

Solution code:
import heapq

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

class Dijkstra:
    def dijkstra(self, adj, start, goal=None):

        num = N  # グラフのノード数
        dist = [float('inf') for i in range(num)]  # 始点から各頂点までの最短距離を格納する
        prev = [float('inf') for i in range(num)]  # 最短経路における，その頂点の前の頂点のIDを格納する

        dist[start] = 0
        q = []  # プライオリティキュー．各要素は，(startからある頂点vまでの仮の距離, 頂点vのID)からなるタプル
        heapq.heappush(q, (0, start))  # 始点をpush

        for i in range(num-1):
            prov_cost, src = heapq.heappop(q)  # pop

            # プライオリティキューに格納されている最短距離が，現在計算できている最短距離より大きければ，distの更新をする必要はない
            if dist[src] < prov_cost:
                continue

            # 他の頂点の探索
            for dest, cost in adj[src].items():
                if dist[dest] > dist[src] + cost:
                    dist[dest] = dist[src] + cost  # distの更新
                    heapq.heappush(q, (dist[dest], dest))  # キューに新たな仮の距離の情報をpush
                    prev[dest] = src  # 前の頂点を記録

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

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

        # 終点から最短経路を逆順に辿る
        while prev[dest] != float('inf'):
            path.append(prev[dest])
            dest = prev[dest]

        # 経路をreverseして出力
        return list(reversed(path))

from collections import defaultdict
Ey = defaultdict(lambda: defaultdict(lambda: float("inf")))
Es = defaultdict(lambda: defaultdict(lambda: float("inf")))


E = [list(map(int, input().split())) for i in range(M)]

for e in E:
    u, v, a, b = e
    Ey[u-1][v-1] = Ey[v-1][u-1] = a
    Es[u-1][v-1] = Es[v-1][u-1] = b

dj = Dijkstra()
Dy = dj.dijkstra(Ey, S-1)
Ds = dj.dijkstra(Es, T-1)
mi = float("inf")
Ans = [0] * N
for i in range(N-1, -1, -1):
    mi = min(mi, Dy[i]+Ds[i])
    Ans[i] = mi
for a in Ans:
    print(10**15-a)