Problem:


Score : 600 points

Problem Statement

We have N points numbered 1 to N arranged in a line in this order.

Takahashi decides to make an undirected graph, using these points as the vertices.
In the beginning, the graph has no edge. Takahashi will do M operations to add edges in this graph.
The i-th operation is as follows:

The operation uses integers L_i and R_i between 1 and N (inclusive), and a positive integer C_i. For every pair of integers (s, t) such that L_i \leq s < t \leq R_i, add an edge of length C_i between Vertex s and Vertex t.

The integers L_1, ..., L_M, R_1, ..., R_M, C_1, ..., C_M are all given as input.

Takahashi wants to solve the shortest path problem in the final graph obtained. Find the length of the shortest path from Vertex 1 to Vertex N in the final graph.

Constraints

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq L_i < R_i \leq N

1 \leq C_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N M
L_1 R_1 C_1
:
L_M R_M C_M

Output

Print the length of the shortest path from Vertex 1 to Vertex N in the final graph.
If there is no shortest path, print -1 instead.

Sample Input 1

4 3
1 3 2
2 4 3
1 4 6

Sample Output 1

5

We have an edge of length 2 between Vertex 1 and Vertex 2, and an edge of length 3 between Vertex 2 and Vertex 4, so there is a path of length 5 between Vertex 1 and Vertex 4.

Sample Input 2

4 2
1 2 1
3 4 2

Sample Output 2

-1

Sample Input 3

10 7
1 5 18
3 4 8
1 3 5
4 7 10
5 9 8
6 10 5
8 10 3

Sample Output 3

28



Sample input:
4 3
1 3 2
2 4 3
1 4 6


Sample output:
5

Submission status: Accepted

Solution code:
from heapq import heappush, heappop

N, M = map(int, input().split())
graph = [[] for i in range(N)]
for i in range(1, N):
  graph[i].append((i-1, 0))

for i in range(M):
  l, r, c = map(int, input().split())
  graph[l-1].append((r-1, c))

dist = [-1] * N
d = [(0, 0)]
while d:
  cost, node = heappop(d)
  if dist[node] >= 0:
    continue
  dist[node] = cost
  for child, c in graph[node]:
    if dist[child] >= 0:
      continue
    heappush(d, (cost+c, child))

print(dist[-1])

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import sys
from bisect import bisect_left,bisect_right
sys.setrecursionlimit(10**9)
INF=10**18
MOD=10**9+7
input=lambda: sys.stdin.readline().rstrip()
YesNo=lambda b: bool([print('Yes')] if b else print('No'))
YESNO=lambda b: bool([print('YES')] if b else print('NO'))
int1=lambda x:int(x)-1

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

edge=[[] for _ in range(N)]
for i in range(N-1):
    edge[i+1].append((0,i))
for _ in range(M):
    l,r,c=map(int,input().split())
    l-=1
    r-=1
    edge[l].append((c,r))

from heapq import heappop,heappush
# edges=[[(cost1,v1),(cost2,v2)],...]
def dijkstra(start,n,edges):
    d=[INF]*n
    used=[False]*n
    d[start]=0
    used[start]=True
    edgelist=[]
    for edge in edges[start]:
        heappush(edgelist,edge)
    while edgelist:
        minedge=heappop(edgelist)
        if used[minedge[1]]:
            continue
        v=minedge[1]
        d[v]=minedge[0]
        used[v]=True
        for edge in edges[v]:
            if not used[edge[1]]:
                heappush(edgelist,(edge[0]+d[v],edge[1]))
    return d

d=dijkstra(0,N,edge)
print(d[-1] if d[-1]!=INF else -1)

Submission status: Accepted

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

def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))

def main():
    N,M=MI()
    inf=10**16

    ##########################################
    import heapq
    class Dijkstra():
        """
        ・有向 / 無向は問わない(無向の場合は，逆向きの辺もたす)
        ・負のコストがない場合のみ
        ・計算量はO(E log|V|)　
        ・heapを使うことで頂点を走査する必要がなくなる（代わりに，距離更新したものは確定でなくともqueに入れておく）
        """
        
        #最短のpathをたす
        
        
        class Edge():
            #重み付き有向辺
            
            def __init__(self, _to, _cost):
                self.to =_to
                self.cost = _cost
        
        def __init__(self, V):
            #引数Vは頂点数
            self.G = [[] for _ in range(V)] #隣接リストG[u][i]が頂点uのi番目の辺
            self. _E = 0 #辺の数
            self._V = V #頂点数
        
        #proparty - 辺の数
        def E(self):
            return self._E
        
        #proparty - 頂点数
        def V(self):
            return self._V
        
        def add(self, _from, _to, _cost):
            #2頂点と辺のコストを追加
            self.G[_from].append(self.Edge(_to,_cost))
            self._E +=1
            
        def add2(self, _from, _to, _cost):
            #2頂点と辺のコスト（無向）を追加
            self.G[_from].append(self.Edge(_to, _cost))
            self.G[_to].append(self.Edge(_from, _cost))
            self._E +=2
            
        def shortest_path(self,s):#,g):
            #始点sから頂点iまでの最短経路長のリストを返す
            
            que = [] #priority queue
            d = [inf] * self.V()
            prev = [None]*self.V() #prev[j]は，sからjへ最短経路で行くときのjの一つ前の場所
            d[s] = 0
            heapq.heappush(que,(0,s)) #始点の距離と頂点番号をヒープに追加
            
            while len(que)!=0:
                #キューに格納されてある中で一番コストが小さい頂点を取り出す
                cost,v = heapq.heappop(que)
                
                #キューに格納された最短経路長候補がdの距離よりも大きい場合に処理をスキップ
                if d[v] < cost:
                    continue
                    
                #頂点vに隣接する各頂点iに対して，vを経由した場合の距離を計算して，これがd[i]よりも小さい場合に更新
                for i in range(len(self.G[v])):
                    e = self.G[v][i] #vのi個目の隣接辺
                    if d[e.to] > d[v] + e.cost:
                        d[e.to] = d[v] + e.cost #更新
                        prev[e.to] = v
                        heapq.heappush(que,(d[e.to],e.to)) #queに新たな最短経路長候補を追加
            
            """#sからgまでの最短経路
            path = []
            pos = g #今いる場所，ゴールで初期化
            for _ in range(self.V()+1):
                path.append(pos)
                if pos == s:
                    break
                #print("pos:",format(pos))
                pos = prev[pos]
            path.reverse()
            #print(path)"""
                        
            return d#,path
    ########################
    
    djk=Dijkstra(N)

    for i in range(M):
        l,r,c=MI()
        l-=1
        r-=1
        djk.add(l,r,c)
        
    for i in range(1,N):
        djk.add(i,i-1,0)

        
    d=djk.shortest_path(0)
    ans=d[-1]



    
    
    if ans>=inf:
        print(-1)
    else:
        print(ans)
    
        
    
        
        
    

main()

Submission status: Accepted

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

def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))

def main():
    N,M=MI()
    inf=10**16
    class SegTree:
        def __init__(self,N,ide,segfunc=min):
            self.ide_ele = ide
            """
            ex)
             最小値のセグ木 → +inf
              和のセグ木 → 0
              積のセグ木 → 1
              gcdのセグ木 → 0
            """
            
            self.segfunc=segfunc
            
            #num:N以上の最小の2のべき乗
            self.num =2**(N-1).bit_length()
            self.seg=[self.ide_ele]*2*self.num




        #リストで初期化する
        def setL(self,init_val):
            #init_valは操作する数列
            for i in range(N):
                self.seg[i+self.num-1]=init_val[i]    
            #built
            for i in range(self.num-2,-1,-1) :
                self.seg[i]=self.segfunc(self.seg[2*i+1],self.seg[2*i+2]) 


        #k番目の値をxに更新
        def update(self,k,x):
            k += self.num-1
            self.seg[k] = x
            while k:
                k = (k-1)//2
                self.seg[k] = self.segfunc(self.seg[k*2+1],self.seg[k*2+2])


        #[p,q)の区間に対するクエリへの応答
        def query(self,p,q):
            if q<=p:
                return self.ide_ele
            p += self.num-1
            q += self.num-2
            res=self.ide_ele
            while q-p>1:
                if p&1 == 0:
                    res = self.segfunc(res,self.seg[p])
                if q&1 == 1:
                    res = self.segfunc(res,self.seg[q])
                    q -= 1
                p = p//2
                q = (q-1)//2
            if p == q:
                res = self.segfunc(res,self.seg[p])
            else:
                res = self.segfunc(self.segfunc(res,self.seg[p]),self.seg[q])
            return res


    seg=SegTree(N+1,inf,min)
    
    L=[0]*M
    R=[0]*M
    C=[0]*M
    for i in range(M):
        l,r,c=MI()
        l-=1
        r-=1
        L[i]=l
        R[i]=r
        C[i]=c
        
    R,C,L=zip(*sorted(zip(R,C,L)))
        
    
    
    #rが小さいものから見て(rが同じならcが小さい)確定させていく
    now=0#確定させたとこと
    seg.update(0,0)
    
    for i in range(M):
        r=R[i]
        l=L[i]
        c=C[i]
        m=seg.query(l,now+1)#移動もとの範囲での最小値
        #seg.update(r,m+c)
        now=r
        
        #このままだと入力例3みたいに，コストは低いけどl,rがちかいみたいなのを先に処理してしまう
        #とりあえず右端だけ更新しとけばokか?
        
        if m+c<seg.query(now,now+1):
            seg.update(now,m+c)
        
        #print((l+1,r+1,c),now+1,m,m+c)
        """
        for ii in range(N):
            print(seg.query(ii,ii+1))"""
        
    ans=seg.query(N-1,N)

    
    
    if ans>=inf:
        print(-1)
    else:
        print(ans)
    
        
    
        
        
    

main()

Submission status: Accepted

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

INF = 10 ** 15

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

LRCs = [tuple(map(int, input().split())) for _ in range(M)]
LRCs.sort(key = lambda t: (t[1], t[0]))

dp = [INF] * N
dp[0] = 0
for L, R, C in LRCs:
    while dp[R-1] > dp[L-1] + C:
        dp[R-1] = dp[L-1] + C
        R -= 1

if dp[-1] == INF:
    print(-1)
else:
    print(dp[-1])

Submission status: Accepted

Solution code:
import sys,bisect,string,math,time,functools,random,fractions
from heapq import heappush,heappop,heapify
from collections import deque,defaultdict,Counter
from itertools import permutations,combinations,groupby
def Golf():n,*t=map(int,open(0).read().split())
def I():return int(input())
def S_():return input()
def IS():return input().split()
def LS():return [i for i in input().split()]
def LI():return [int(i) for i in input().split()]
def LI_():return [int(i)-1 for i in input().split()]
def NI(n):return [int(input()) for i in range(n)]
def NI_(n):return [int(input())-1 for i in range(n)]
def StoLI():return [ord(i)-97 for i in input()]
def ItoS(n):return chr(n+97)
def LtoS(ls):return ''.join([chr(i+97) for i in ls])
def GI(V,E,ls=None,Directed=False,index=1):
    org_inp=[];g=[[] for i in range(V)]
    FromStdin=True if ls==None else False
    for i in range(E):
        if FromStdin:
            inp=LI()
            org_inp.append(inp)
        else:
            inp=ls[i]
        if len(inp)==2:
            a,b=inp;c=1
        else:
            a,b,c=inp
        if index==1:a-=1;b-=1
        aa=(a,c);bb=(b,c);g[a].append(bb)
        if not Directed:g[b].append(aa)
    return g,org_inp
def GGI(h,w,search=None,replacement_of_found='.',mp_def={'#':1,'.':0},boundary=1):
#h,w,g,sg=GGI(h,w,search=['S','G'],replacement_of_found='.',mp_def={'#':1,'.':0},boundary=1) # sample usage
    mp=[boundary]*(w+2);found={}
    for i in range(h):
        s=input()
        for char in search:
            if char in s:
                found[char]=((i+1)*(w+2)+s.index(char)+1)
                mp_def[char]=mp_def[replacement_of_found]
        mp+=[boundary]+[mp_def[j] for j in s]+[boundary]
    mp+=[boundary]*(w+2)
    return h+2,w+2,mp,found
def TI(n):return GI(n,n-1)
def bit_combination(n,base=2):
    rt=[]
    for tb in range(base**n):s=[tb//(base**bt)%base for bt in range(n)];rt+=[s]
    return rt
def gcd(x,y):
    if y==0:return x
    if x%y==0:return y
    while x%y!=0:x,y=y,x%y
    return y
def show(*inp,end='\n'):
    if show_flg:print(*inp,end=end)
 
YN=['YES','NO'];Yn=['Yes','No']
mo=10**9+7
inf=float('inf')
FourNb=[(-1,0),(1,0),(0,1),(0,-1)];EightNb=[(-1,0),(1,0),(0,1),(0,-1),(1,1),(-1,-1),(1,-1),(-1,1)];compas=dict(zip('WENS',FourNb));cursol=dict(zip('LRUD',FourNb))
l_alp=string.ascii_lowercase
#sys.setrecursionlimit(10**7)
read=sys.stdin.buffer.read
readline=sys.stdin.buffer.readline
input=lambda: sys.stdin.readline().rstrip()

class Tree:
    def __init__(self,inp_size=None,ls=None,init=True,index=0):
        self.LCA_init_stat=False
        self.ETtable=[]
        if init:
            if ls==None:
                self.stdin(inp_size,index=index)
            else:
                self.size=len(ls)+1
                self.edges,_=GI(self.size,self.size-1,ls,index=index)
        return
 
    def stdin(self,inp_size=None,index=1):
        if inp_size==None:
            self.size=int(input())
        else:
            self.size=inp_size
        self.edges,_=GI(self.size,self.size-1,index=index)
        return
    
    def listin(self,ls,index=0):
        self.size=len(ls)+1
        self.edges,_=GI(self.size,self.size-1,ls,index=index)
        return
 
    def __str__(self):
        return  str(self.edges)
 
    def dfs(self,x,func=lambda prv,nx,dist:prv+dist,root_v=0):
        q=deque()
        q.append(x)
        v=[-1]*self.size
        v[x]=root_v
        while q:
            c=q.pop()
            for nb,d in self.edges[c]:
                if v[nb]==-1:
                    q.append(nb)
                    v[nb]=func(v[c],nb,d)
        return v
 
    def EulerTour(self,x):
        q=deque()
        q.append(x)
        self.depth=[None]*self.size
        self.depth[x]=0
        self.ETtable=[]
        self.ETdepth=[]
        self.ETin=[-1]*self.size
        self.ETout=[-1]*self.size
        cnt=0
        while q:
            c=q.pop()
            if c<0:
                ce=~c
            else:
                ce=c
                for nb,d in self.edges[ce]:
                    if self.depth[nb]==None:
                        q.append(~ce)
                        q.append(nb)
                        self.depth[nb]=self.depth[ce]+1
            self.ETtable.append(ce)
            self.ETdepth.append(self.depth[ce])
            if self.ETin[ce]==-1:
                self.ETin[ce]=cnt
            else:
                self.ETout[ce]=cnt
            cnt+=1
        return
    
    def LCA_init(self,root):
        self.EulerTour(root)
        self.st=SparseTable(self.ETdepth,init_func=min,init_idl=inf)
        self.LCA_init_stat=True
        return
    
    def LCA(self,root,x,y):
        if self.LCA_init_stat==False:
            self.LCA_init(root)
        xin,xout=self.ETin[x],self.ETout[x]
        yin,yout=self.ETin[y],self.ETout[y]
        a=min(xin,yin)
        b=max(xout,yout,xin,yin)
        id_of_min_dep_in_et=self.st.query_id(a,b+1)
        return self.ETtable[id_of_min_dep_in_et]
 
class SparseTable: # O(N log N) for init, O(1) for query(l,r)
    def __init__(self,ls,init_func=min,init_idl=float('inf')):
        self.func=init_func
        self.idl=init_idl
        self.size=len(ls)
        self.N0=self.size.bit_length()
        self.table=[ls[:]]
        self.index=[list(range(self.size))]
        self.lg=[0]*(self.size+1)
        
        for i in range(2,self.size+1):
            self.lg[i]=self.lg[i>>1]+1
 
        for i in range(self.N0):
            tmp=[self.func(self.table[i][j],self.table[i][min(j+(1<<i),self.size-1)]) for j in range(self.size)]
            tmp_id=[self.index[i][j] if self.table[i][j]==self.func(self.table[i][j],self.table[i][min(j+(1<<i),self.size-1)]) else self.index[i][min(j+(1<<i),self.size-1)] for j in range(self.size)]
            self.table+=[tmp]
            self.index+=[tmp_id]
    
    # return func of [l,r)
    def query(self,l,r):
        if r>self.size:r=self.size
        #N=(r-l).bit_length()-1
        N=self.lg[r-l]
        return self.func(self.table[N][l],self.table[N][max(0,r-(1<<N))])
    
    # return index of which val[i] = func of v among [l,r)
    def query_id(self,l,r):
        if r>self.size:r=self.size
        #N=(r-l).bit_length()-1
        N=self.lg[r-l]
        a,b=self.index[N][l],self.index[N][max(0,r-(1<<N))]
        if self.table[0][a]==self.func(self.table[N][l],self.table[N][max(0,r-(1<<N))]):
            b=a
        return b
    
    def __str__(self):
        return str(self.table[0])
 
    def print(self):
        for i in self.table:
            print(*i)

def dijkstra(edge,st):
    # edge=[[(v_to,dist_to_v),...],[],...]
    # initialize: def: d=dist(st,i), prev=[previous vertex in minimum path], q[]
    n=len(edge)
    d=[(0 if st==i else inf) for i in range(n)]
    prev=[0]*n
    q=[(j,i) for i,j in enumerate(d)]
    heapify(q)
    v=[False]*n
    # calc
    while q:
        dist,cur=heappop(q)
        if v[cur]:
            continue
        v[cur]=True
        for dst,dist in edge[cur]:
            alt=d[cur]+dist
            if alt<d[dst]:
                d[dst]=alt
                prev[dst]=cur
                heappush(q,(alt,dst))
    return d,prev

show_flg=False
show_flg=True
ans=0



n,m=LI()
g,_=GI(n,0)
p=[0]*(n+1)
for i in range(m):
    l,r,c=LI_()
    c+=1
    g[l].append((r,c))
    p[l]+=1
    p[r]-=1

for i in range(n):
    p[i+1]+=p[i]
    if p[i+1]>0:
        g[i+1].append((i,0))

d,_=dijkstra(g,0)
ans=d[n-1]
if ans==inf:
    ans=-1

print(ans)

Submission status: Accepted

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

INF = 10**18

def dijkstra(edges, size, src):
    from heapq import heappush, heappop

    dist = [INF] * size
    dist[src] = 0
    pq = [(0, src)]
    while pq:
        d, v = heappop(pq)
        if d > dist[v]:
            continue
        for u, weight in edges[v]:
            nd = d + weight
            if dist[u] > nd:
                dist[u] = nd
                heappush(pq, (nd, u))
    return dist

N, M = map(int, input().split())
G = [[] for _ in range(N+1)]
for i in range(2, N+1):
    G[i].append((i - 1, 0))
for _ in range(M):
    L, R, C = map(int, input().split())
    G[L].append((R, C))
dist = dijkstra(G, N+1, 1)
print(dist[N] if dist[N] < INF else -1)

Submission status: Accepted

Solution code:
n, m = map(int, input().split())
inf = 10 ** 15
edges = [[] for _ in range(n)]
for _ in range(m):
    l, r, c = map(int, input().split())
    edges[l-1].append((r-1, c))
for i in range(n-1):
    edges[i+1].append((i, 0))

from heapq import heappop, heappush
d = [inf for _ in range(n)]
def dijkstra(s):
    que = []
    d[s] = 0
    heappush(que, (0, s))

    while len(que):
        dist, node = heappop(que)

        if d[node] < dist:
            continue
        for to, cost in edges[node]:
            if d[to] > dist + cost:
                d[to] = dist + cost
                heappush(que, (d[to], to))

dijkstra(0)

print(d[n-1] if d[n-1] != inf else -1)

Submission status: Accepted

Solution code:
import heapq

n,m = map(int, input().split())
to= [list() for _ in range(n)]
for i in range(m):
    l,r,c = map(int, input().split())
    l-=1
    r-=1
    to[l].append((r,c))

for i in range(1,n):
    to[i].append((i-1,0))

q = []
INF = 1001001001001001
d = [INF]*n
d[0]=0
heapq.heappush(q,(0,0))
while q:
    cost,u = heapq.heappop(q)
    if d[u]<cost:
        continue
    for v,c in to[u]:
        if d[v]>d[u]+c:
            d[v]=d[u]+c
            heapq.heappush(q,(d[v],v))

if d[-1]==INF:
    print(-1)
else:
    print(d[-1])

Submission status: Accepted

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


def dijkstra1(V, n, inf, source):
    # O(ElogV)

    dist = [inf] * (n+1)
    dist[source] = 0
    q = [(0, source)]

    while q:
        cost, u = heappop(q)
        if dist[u] < cost:
            continue
        for c, v in V[u]:
            if dist[v] > dist[u] + c:
                dist[v] = dist[u] + c
                heappush(q, (dist[v], v))

    return dist


def solve():
    N, M = map(int, input().split())
    INF = 10**20
    l = []
    V = defaultdict(list)

    for _ in range(M):
        L, R, C = map(int, input().split())
        V[L].append((C, R))

    for i in range(1, N):
        V[i+1].append((0, i))

    dj = dijkstra1(V, N, INF, 1)
    print(dj[N] if dj[N]!=INF else -1)


if __name__ == "__main__":
    solve()

Submission status: Accepted

Solution code:
INF = 10 ** 15
MOD = 10 ** 9 + 7 
from heapq import heappop,heappush,heapify
def dijkstra(G,start = 0):
    N = len(G)
    dist = [INF] *N
    dist[start] = 0
    q = [(0,start)]

    while q:
        d,v = heappop(q)
        if d > dist[v]:
            continue
        for e,c in G[v]:
            if dist[v] + c < dist[e]:
                dist[e] = dist[v] + c
                heappush(q,(dist[e],e))
    return dist[-1]

def main():
    N,M = map(int,input().split())
    G = [[] for _ in range(N)]
    for _ in range(M):
        l,r,c = map(int,input().split())
        l -= 1
        r -= 1
        G[l].append((r,c))
        G[r].append((l,c))
    for i in range(N - 1):
        G[i + 1].append((i,0))
    ans = dijkstra(G)
    print(ans if ans < INF else -1)
if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
INF = 10 ** 15
MOD = 10 ** 9 + 7 

class SegmentTree():
    f = min
    unit = INF
   
    def __init__(self,array):
        self.N = len(array)
        self.tree = [self.unit] * (2*self.N)
        self._build(array)
    
    def _build(self,array):
        for i,x in enumerate(array,self.N):
            self.tree[i] = x
        for i in range(self.N - 1,0,-1):
            self.tree[i] = self.f(self.tree[i << 1],self.tree[i << 1|1])
    
    def update(self,k,x):
        k += self.N
        if self.tree[k] <= x:
            return 
        self.tree[k] = x
        while k > 1:
            k >>= 1
            self.tree[k] = self.f(self.tree[k << 1],self.tree[k << 1|1])
    
    def query(self,l,r):
        l += self.N
        r += self.N
        vl = self.unit
        vr = self.unit
        while l < r:
            if l&1: 
                vl = self.f(vl,self.tree[l])
                l += 1
            if r&1:
                r -= 1
                vr = self.f(self.tree[r],vr)
            l >>= 1
            r >>= 1
        return self.f(vl,vr)
    
    def __str__(self):
        return '\n'.join(' '.join(str(v) for v in self.tree[1<<i:1<<(i + 1)]) for i in range((2*self.N).bit_length()))

N,M = map(int,input().split())
paths = [[] for _ in range(N)]
for _ in range(M):
    l,r,c = map(int,input().split())
    l -= 1
    r -= 1
    paths[l].append((r,c))

dp = SegmentTree([0] + [INF] * (N - 1))
for l,path in enumerate(paths):
    for r,c in path:
        before_min = dp.query(l,N)
        dp.update(r,before_min + c)
ans = dp.query(N - 1,N)
print(ans if ans < INF else -1)

Submission status: Accepted

Solution code:
class Dijkstra():
    """ ダイクストラ法
    重み付きグラフにおける単一始点最短路アルゴリズム

    * 使用条件
        - 負のコストがないこと
        - 有向グラフ、無向グラフともにOK

    * 計算量はO(E*log(V))

    * ベルマンフォード法より高速なので、負のコストがないならばこちらを使うとよい
    """
    class Edge():
        """ 重み付き有向辺 """
        def __init__(self, _to, _cost):
            self.to = _to
            self.cost = _cost

    def __init__(self, V):
        """ 重み付き有向辺
        無向辺を表現したいときは、_fromと_toを逆にした有向辺を加えればよい

        Args:
            V(int): 頂点の数
        """
        self.G = [[] for i in range(V)]  # 隣接リストG[u][i] := 頂点uのi個目の隣接辺
        self._E = 0  # 辺の数
        self._V = V  # 頂点の数

    @property
    def E(self):
        """ 辺数
        無向グラフのときは、辺数は有向グラフの倍になる
        """
        return self._E

    @property
    def V(self):
        """ 頂点数 """
        return self._V

    def add(self, _from, _to, _cost):
        """ 2頂点と、辺のコストを追加する """
        self.G[_from].append(self.Edge(_to, _cost))
        self._E += 1

    def shortest_path(self,s):
        import heapq
        que=[]
        d=[10**15]*self.V
        d[s]=0
        last=-1
        heapq.heappush(que,(0,s))

        while len(que)!=0:
            cost,v=heapq.heappop(que)

            if d[v]<cost:continue

            for i in range(last+1,v+1):
                d[i]=cost
                for j in range(len(self.G[i])):
                    e=self.G[i][j]
                    if d[e.to]>d[i]+e.cost:
                        d[e.to]=d[i]+e.cost
                        heapq.heappush(que,(d[e.to],e.to))
            last=v
        return d


import sys

N,M=map(int,input().split())
pro=Dijkstra(N)
for i in range(M):
    l,r,c=map(int,input().split())
    pro.add(l-1,r-1,c)

ans=pro.shortest_path(0)[-1]
if ans==10**15:
    print(-1)
else:
    print(ans)

Submission status: Accepted

Solution code:
from heapq import *
import sys
from collections import *
from itertools import *
from decimal import *
import copy
from bisect import *
import time
import math
sys.setrecursionlimit(4100000)
def gcd(a,b):
    if(a%b==0):return(b)
    return (gcd(b,a%b))

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


stack=[[0,-1,0]]
idle_max=10**18
visited=[idle_max for i in range(N+1)]
visited2=[0 for i in range(N+1)]
visited[1]=0
x=0
while stack:
    #print(stack)
    m,a,p=heappop(stack)
    a=-a
    if a==N:
        print(m)
        break
    if not visited2[a]:
        visited2[a]=1
        for i in range(x,M):
            l,r,c=LRC[i]
            x=i
            if l<=a:
                _m=m+c
                if _m<visited[r]:
                    visited[r]=_m
                    heappush(stack,[_m,-r,a+1])
            else:
                break
else:
    print(-1)

Submission status: Accepted

Solution code:
import sys
from operator import itemgetter

sys.setrecursionlimit(10 ** 7)
rl = sys.stdin.readline


class SegmentTree:
    def __init__(self, init_value: list, segfunc, ide_ele):
        n = len(init_value)
        self.N0 = 1 << (n - 1).bit_length()
        self.ide_ele = ide_ele
        self.data = [ide_ele] * (2 * self.N0)
        self.segfunc = segfunc
        
        for i, x in enumerate(init_value):
            self.data[i + self.N0 - 1] = x
        for i in range(self.N0 - 2, -1, -1):
            self.data[i] = self.segfunc(self.data[2 * i + 1], self.data[2 * i + 2])
    
    def update(self, k, x):
        k += self.N0 - 1
        ################################################################
        self.data[k] = x
        ################################################################
        while k:
            k = (k - 1) // 2
            self.data[k] = self.segfunc(self.data[k * 2 + 1], self.data[k * 2 + 2])
    
    def query(self, left, right):
        L = left + self.N0
        R = right + self.N0
        res = self.ide_ele
        ################################################################
        
        while L < R:
            if L & 1:
                res = self.segfunc(res, self.data[L - 1])
                L += 1
            if R & 1:
                R -= 1
                res = self.segfunc(res, self.data[R - 1])
            L >>= 1
            R >>= 1
        
        ################################################################
        return res


def solve():
    N, M = map(int, rl().split())
    LRC = [list(map(int, rl().split())) for _ in range(M)]
    LRC.sort(key=itemgetter(0, 1))
    
    INF = 10 ** 18
    dist = [INF] * N
    dist[0] = 0
    seg_tree = SegmentTree(dist, min, INF)
    
    for L, R, C in LRC:
        L, R = L - 1, R - 1
        tmp = seg_tree.query(L, R)
        cost = tmp + C
        if cost < dist[R]:
            dist[R] = cost
            seg_tree.update(R, cost)
    print(dist[-1] if dist[-1] != INF else -1)


if __name__ == '__main__':
    solve()

Submission status: Accepted

Solution code:
n,m = map(int, input().split())
link = [[] for _ in range(n)]
for i in range(m):
    a,b,cost = list(map(int,input().split()))
    link[a-1].append([b-1,cost])
    link[b-1].append([a-1,cost])

for i in range(n-1):
    link[i+1].append([i,0])

from heapq import heappush, heappop,heappushpop,heapify
def dks(g,start,num_v):
    INF=float('inf')
    visited = set()
    hq = []
    heappush(hq, (0,start))
    cost = [INF] * num_v
    while hq:
        shortest, i = heappop(hq)
        if i in visited:
            continue
        visited.add(i)
        cost[i] = shortest
        for j, t in g[i]:
            if j in visited:
                continue
            heappush(hq, (shortest + t, j))
    return cost

ans=dks(link,0,n)
if ans[-1]!=float("inf"):
    print(ans[-1])
else:
    print(-1)

Submission status: Accepted

Solution code:
import heapq
n,m=map(int,input().split())
edge=[[] for _ in range(n)]
for i in range(n-1):
  edge[i+1].append([0,i])
for _ in range(m):
  l,r,c=map(int,input().split())
  l-=1
  r-=1
  edge[l].append([c,r])
  edge[r].append([c,l])
def dijkstra_heap(s):
    #始点sから各頂点への最短距離
    infi=10**18
    d = [infi] * n
    used = [True] * n #True:未確定
    d[s] = 0
    used[s] = False
    edgelist = []
    for e in edge[s]:
        heapq.heappush(edgelist,e)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        #まだ使われてない頂点の中から最小の距離のものを探す
        if not used[minedge[1]]:
            continue
        v = minedge[1]
        d[v] = minedge[0]
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,[e[0]+d[v],e[1]])
    if d[n-1]!=infi:
      return d[n-1]
    else:
      return -1
print(dijkstra_heap(0))

Submission status: Accepted

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

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

# 最小値を求めるセグメント木
def init_min(init_min_val):
    #set_val
    for i in range(n):
        seg_min[i+num_max-1]=init_min_val[i]
    #built
    for i in range(num_max-2,-1,-1) :
        seg_min[i]=min(seg_min[2*i+1],seg_min[2*i+2])

def update_min(k,x):
    k += num_max-1
    seg_min[k] = x
    while k:
        k = (k-1)//2
        seg_min[k] = min(seg_min[k*2+1],seg_min[k*2+2])

def query_min(p,q):
    if q<=p:
        return ide_ele_min
    p += num_max-1
    q += num_max-2
    res=ide_ele_min
    while q-p>1:
        if p&1 == 0:
            res = min(res,seg_min[p])
        if q&1 == 1:
            res = min(res,seg_min[q])
            q -= 1
        p = p//2
        q = (q-1)//2
    if p == q:
        res = min(res,seg_min[p])
    else:
        res = min(min(res,seg_min[p]),seg_min[q])
    return res

#####単位元######
ide_ele_min = 10**20

#num_max:n以上の最小の2のべき乗
# num_max =2**(n-1).bit_length()
num_max = 2**(len(str(bin(n-1))) -2)
seg_min=[ide_ele_min]*2*num_max

update_min(0,0)

rlc = []
for i in range(m):
    l,r,c = map(int,input().split())
    rlc.append((r,l,c))

rlc.sort()

for tmp in rlc:
    r,l,c = tmp
    l = l-1
    r = r-1
    update_min( r, min( query_min(l,r) + c , query_min(r,r+1)) )

ans = query_min(n-1,n)
if(ans == ide_ele_min):
    print(-1)
else:
    print(ans)

Submission status: Accepted

Solution code:
# shortest path on line

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

graph = {i: {} for i in range(1, n + 1)}

for i in range(1, n):
    graph[i + 1][i] = 0

for _ in range(m):
    l, r, c = map(int, input().split())
    if not (r in graph[l].keys()):
        graph[l][r] = c
    else:
        graph[l][r]=min(graph[l][r],c)


###############################################################

import heapq

def dijkstra(s, graph, n):
    # ｓからのグラフの最短最短距離をまとめたデータを返す
    dist = [10**20 for i in range(n + 1)]
    dist[s] = 0
    pq = []
    heapq.heapify(pq)
    # 全ての接点を一度優先度付きキューに挿入する
    heapq.heappush(pq, (0, s))
    while pq:
        x = heapq.heappop(pq)
        node, mini_dis = x[1], x[0]
        for point in graph[node].keys():
            w = graph[node][point]
            # nodeからpointに対して伸びる辺の長さ
            newlen = dist[node] + w
            if newlen < dist[point]:
                heapq.heappush(pq, (newlen, point))
                dist[point] = newlen

    return dist
###############################################################


A = dijkstra(1, graph, n)
if A[n]<10**20:
    print(A[n])
else:
    print(-1)