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: Runtime Error

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

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

MAX_VAL = 10**20
uvab =  [list(map(int,input().split())) for _ in range(m)]
jpy_cost = defaultdict(lambda :defaultdict(lambda :MAX_VAL))
snuke_cost = defaultdict(lambda :defaultdict(lambda :MAX_VAL))


for u,v,a,b in uvab:
    u=u-1
    v=v-1
    jpy_cost[u][v] = a
    jpy_cost[v][u] =a
    snuke_cost[u][v]=b
    snuke_cost[v][u]=b


def dijkstra(glaph, start, goal,g_size):
    def get_path(start, goal, prev):
        path = []
        now = goal
        path.append(now)
        while True:
            path.append(prev[now])
            if prev[now] == start: break
            now = prev[now]
        path.reverse()
        return path
    #g_size = len(glaph)
    visited = [False] * g_size
    cost = [MAX_VAL] * g_size
    prev = [None] * g_size
    cost[start] = 0
    prev[start] = start
    now = start
    while True:
        min = MAX_VAL
        next = -1
        visited[now] = True
        for i in range(g_size):
        #for i in glaph[now]:
            if visited[i]: continue
            if glaph[now][i]:
                tmp_cost = glaph[now][i] + cost[now]
                if cost[i] > tmp_cost:
                    cost[i] = tmp_cost
                    prev[i] = now
            if min > cost[i]:
                min = cost[i]
                next = i
        if next == -1: break
        now = next

    return cost
    #return [get_path(start, goal, prev), cost[goal]]



def dijkstra2(graph, source):
    inf = float('inf')
    dist = defaultdict(lambda: inf)
    previous = {}
    visited = set()

    dist[source] = 0
    graph_nodes = [(dist[n], n) for n in graph.keys()]
    heapify(graph_nodes)
    while graph_nodes:
        _, u = heappop(graph_nodes)
        visited.add(u)
        if dist[u] == inf:
            break

        for v in graph[u]:
            if v in visited:
                continue
            alt = dist[u] + graph[u][v]
            if alt < dist[v]:
                i = graph_nodes.index((dist[v], v))
                graph_nodes[i] = (alt, v)
                heapify(graph_nodes)

                dist[v] = alt
                previous[v] = u

    return dist


#jpy_dijk = (dijkstra(jpy_cost,s-1,s-1,n))
#snuke_dijk = (dijkstra(snuke_cost,t-1,t-1,n))
jpy_dijk = (dijkstra2(jpy_cost,s-1))
snuke_dijk = (dijkstra2(snuke_cost,t-1))
raise

#print(s,t)
#print(jpy_dijk)
#print(snuke_dijk)
#print([jpy_dijk[i]+snuke_dijk[i] for i in range(n)])

#ord n
res = []
min_val = MAX_VAL
for i in reversed(range(n)):
    #都市  i で両替
    val = jpy_dijk[i]+ snuke_dijk[i]
    assert val < MAX_VAL
    min_val=min(min_val,val)
    res.append(min_val)
#ord n
for x in reversed(res):
    print(10**15-  x)

Submission status: Runtime Error

Solution code:
from collections import defaultdict
n,m,s,t=map(int, input().split())
s-=1
t-=1
yen={}
snk={}
adj=defaultdict(list)
for _ in range(m):
    u,v,a,b=map(int, input().split())
    u-=1    
    v-=1    
    adj[u].append(v)
    adj[v].append(u)
    yen[(u,v)]=a
    yen[(v,u)]=a
    snk[(u,v)]=b
    snk[(v,u)]=b

d=[float('inf')]*n
d[s]=0
prev={}
q=list(range(n))
while q!=[]:
    md=float('inf')    
    for qi in q:
        md=min(md,d[qi])
    u=q.pop(q.index(d.index(md)))
    for v in adj[u]:
        if d[v]>d[u]+yen[(u,v)]:
            d[v]=d[u]+yen[(u,v)]
            prev[v]=u
# tr=t
# while tr!=s:
#     print(tr,'->')
#     tr=prev[tr]
# print(s)
dr=[float('inf')]*n
dr[t]=0
prevr={}
qr=list(range(n))
while qr!=[]:
    md=float('inf')    
    for qi in qr:
        md=min(md,dr[qi])
    u=qr.pop(qr.index(dr.index(md)))
    for v in adj[u]:
        if dr[v]>dr[u]+snk[(u,v)]:
            dr[v]=dr[u]+snk[(u,v)]
            prevr[v]=u
while d!=[]:
    ans=float('inf')
    for y,s in zip(d,dr):
        ans=min(ans, y+s)
        if ans==y+s:
            ai=d.index(y)
    print(10**15-ans)
    del d[0]
    del dr[0]

Submission status: Runtime Error

Solution code:
import numpy as np
n, m, s, t = map(int, input().split())
s -= 1
t -= 1

a = np.zeros((n, n)) + np.inf
b = np.zeros((n, n)) + np.inf
for i in range(n):
  a[i, i] = 0
  b[i, i] = 0
  
for _ in range(m):
  u, v, a_, b_ = map(int, input().split())
  u -= 1
  v -= 1
  a[u, v] = a_
  a[v, u] = a_
  b[u, v] = b_
  b[v, u] = b_
  

for i in range(n):

  yensun = np.zeros((n, 2)) - np.inf

  yensun[s, 0] = 1e15
  yensun[i:, 1] = yensun[i:].max(-1)


  while True:
    new_yensun = yensun.copy()

    new_yensun[:, 0] = (yensun[:,0] - a).max(1)
    new_yensun[:, 1] = (yensun[:,1] - b).max(1)
    new_yensun[i:, 1] = new_yensun[i:].max(-1)
  
    if (new_yensun - yensun).any():
      yensun = new_yensun
    else:
      break
  
  print(yensun[t, 1].astype(np.int))

Submission status: Runtime Error

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

MAX_VAL = 10**20
uvab =  [list(map(int,input().split())) for _ in range(m)]
jpy_cost = defaultdict(lambda :defaultdict(lambda :MAX_VAL))
snuke_cost = defaultdict(lambda :defaultdict(lambda :MAX_VAL))


for u,v,a,b in uvab:
    u=u-1
    v=v-1
    jpy_cost[u][v] = a
    jpy_cost[v][u] =a
    snuke_cost[u][v]=b
    snuke_cost[v][u]=b


def dijkstra(glaph, start, goal,g_size):
    def get_path(start, goal, prev):
        path = []
        now = goal
        path.append(now)
        while True:
            path.append(prev[now])
            if prev[now] == start: break
            now = prev[now]
        path.reverse()
        return path
    #g_size = len(glaph)
    visited = [False] * g_size
    cost = [MAX_VAL] * g_size
    prev = [None] * g_size
    cost[start] = 0
    prev[start] = start
    now = start
    while True:
        min = MAX_VAL
        next = -1
        visited[now] = True
        #for i in range(g_size):
        for i in glaph[now]:
            if visited[i]: continue
            if glaph[now][i]:
                tmp_cost = glaph[now][i] + cost[now]
                if cost[i] > tmp_cost:
                    cost[i] = tmp_cost
                    prev[i] = now
            if min > cost[i]:
                min = cost[i]
                next = i
        if next == -1: break
        now = next

    return cost
    #return [get_path(start, goal, prev), cost[goal]]


jpy_dijk = (dijkstra(jpy_cost,s-1,s-1,n))
snuke_dijk = (dijkstra(snuke_cost,t-1,t-1,n))

#print(s,t)
#print(jpy_dijk)
#print(snuke_dijk)
#print([jpy_dijk[i]+snuke_dijk[i] for i in range(n)])

#ord n
res = []
min_val = MAX_VAL
for i in reversed(range(n)):
    #都市  i で両替
    val = jpy_dijk[i]+ snuke_dijk[i]
    assert val < MAX_VAL
    min_val=min(min_val,val)
    res.append(min_val)
#ord n
for x in reversed(res):
    print(10**15-  x)

Submission status: Runtime Error

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

MAX_VAL = 10**20
uvab =  [list(map(int,input().split())) for _ in range(m)]
jpy_cost = defaultdict(lambda :defaultdict(lambda :MAX_VAL))
snuke_cost = defaultdict(lambda :defaultdict(lambda :MAX_VAL))


for u,v,a,b in uvab:
    u=u-1
    v=v-1
    jpy_cost[u][v] = a
    jpy_cost[v][u] =a
    snuke_cost[u][v]=b
    snuke_cost[v][u]=b


def dijkstra(glaph, start, goal,g_size):
    def get_path(start, goal, prev):
        path = []
        now = goal
        path.append(now)
        while True:
            path.append(prev[now])
            if prev[now] == start: break
            now = prev[now]
        path.reverse()
        return path
    #g_size = len(glaph)
    visited = [False] * g_size
    cost = [MAX_VAL] * g_size
    prev = [None] * g_size
    cost[start] = 0
    prev[start] = start
    now = start
    while True:
        min = MAX_VAL
        next = -1
        visited[now] = True
        #for i in range(g_size):
        for i in glaph[now]:
            if visited[i]: continue
            if glaph[now][i]:
                tmp_cost = glaph[now][i] + cost[now]
                if cost[i] > tmp_cost:
                    cost[i] = tmp_cost
                    prev[i] = now
            if min > cost[i]:
                min = cost[i]
                next = i
        if next == -1: break
        now = next

    return cost
    #return [get_path(start, goal, prev), cost[goal]]


jpy_dijk = (dijkstra(jpy_cost,s-1,0,n))
snuke_dijk = (dijkstra(snuke_cost,t-1,0,n))

#print(jpy_dijk)
#print(snuke_dijk)
#print([jpy_dijk[i]+snuke_dijk[i] for i in range(n)])

#ord n
res = []
min_val = MAX_VAL
for i in reversed(range(n)):
    #都市  i で両替
    val = jpy_dijk[i]+ snuke_dijk[i]
    assert val < MAX_VAL
    min_val=min(min_val,val)
    res.append(min_val)
#ord n
for x in reversed(res):
    print(10**15-  x)