Problem:
MathJax.Hub.Config({
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
});

D: 次元旅行

問題

次元が $1$ 次元から $N$ 次元まで存在する。
AORイカちゃんは次元間を移動できる。
具体的には、AORイカちゃんが $i$ 次元にいるとき、 $j$ 次元( $i > j$ )には自由に移動する事ができるが、 $k$ 次元( $i < k$ )に移動するには魔法を使う必要がある。

AORイカちゃんは $M$ 種類の魔法が使え、 $1, 2, \dots, M$ と番号が振られている。
$i$ 番目の魔法では $a_i$ 次元から $b_i$ 次元に移動できる。
これは $a_i$ 次元にいるときしか使えない。

$i$ 次元に行くと次元特有の「次元の呪い」を受ける。
$i$ 次元の「次元の呪い」により、AORイカちゃんは $d_i$ ダメージを負う。
$i$ 次元の「次元の呪い」を受けた場合、その後ずっと、 $j$ 次元( $i > j$ )の「次元の呪い」は受けない。

AORイカちゃんが $s$ 次元から $t$ 次元に移動するとき、 負うダメージの合計の最小値を求めよ。
ただし、AORイカちゃんは既に $s$ 次元の「次元の呪い」は受けており、そのダメージは考えないものとする。
また、AORイカちゃんは $t$ 次元に行けることが保証されている。

制約

$2 \leq N \leq 10^5$

$1 \leq M \leq min(10^5, N \times (N - 1) / 2)$

$1 \leq s, t \leq N$

$s \neq t$

$1 \leq d_i \leq 10^3$

$1 \leq a_i < b_i \leq N$

$i \neq j$ のとき $( a_i \neq a_j$ または $b_i \neq b_j )$ をみたす

入力は全て整数で与えられる。

入力形式

入力は以下の形式で与えられる。

$N \ M \ s \ t$

$d_1 \dots d_N$

$a_1 \ b_1$

$a_2 \ b_2$

$\vdots$

$a_M \ b_M$

出力

AORイカちゃんが受けるダメージの合計の最小値を出力せよ。また、末尾に改行も出力せよ。

サンプル

サンプル入力 1

3 1 2 3
1 2 3
1 3

サンプル出力 1

3

サンプル入力 2

3 2 1 2
1 3 2
1 2
1 3

サンプル出力 2

2

サンプル入力 3

7 5 2 3
277 390 2 784 401 641 917
2 5
5 6
1 5
2 4
5 7

サンプル出力 3

401

Solution in JAVA (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.StringTokenizer;



public class Main {

	public static void main(String[] args) {
		IO io = new IO();
		int n = io.nextInt();
		int m = io.nextInt();
		int s = io.nextInt() - 1;
		int t = io.nextInt() - 1;
		int[] d = new int[n];
		for(int i=0;i<n;i++) {
			d[i] = io.nextInt();
		}
		Graph g = new Graph(n);
		for(int i=0;i<n-1;i++) {
			g.addEdge(i+1, i, 0);
		}
		for(int i=0;i<m;i++) {
			int a = io.nextInt() - 1;
			int b = io.nextInt() - 1;
			g.addEdge(a, b, d[b]);
		}
		System.out.println(g.minDistDijkstra(s)[t]);
	}

}
class Graph {
	public static final int INF = 1000000000;
	int n;
	ArrayList<Edge>[] graph;

	@SuppressWarnings("unchecked")
	public Graph(int n) {
		this.n = n;
		this.graph = new ArrayList[n];
		for(int i=0;i<n;i++) {
			graph[i] = new ArrayList<>();
		}
	}

	public void addBidirectionalEdge(int from, int to, int cost) {
		addEdge(from, to, cost);
		addEdge(to, from, cost);
	}
	public void addEdge(int from, int to, int cost) {
		graph[from].add(new Edge(to,cost));
	}

	public int[] minDistDijkstra(int s) {
		int[] dist = new int[n];
		Arrays.fill(dist, INF);
		dist[s] = 0;
		PriorityQueue<Node> q = new PriorityQueue<>();
		q.offer(new Node(0,s));
		while(!q.isEmpty()) {
			Node node = q.poll();
			int v = node.id;
			if (dist[v] < node.dist) {
				continue;
			}
			for(Edge e: graph[v]) {
				if (dist[e.to] > dist[v] + e.cost) {
					dist[e.to] = dist[v] + e.cost;
					q.add(new Node(dist[e.to], e.to));
				}
			}
		}
		return dist;
	}
	class Edge {
		int to,cost;
		public Edge(int to, int cost) {
			this.to = to;
			this.cost = cost;
		}
	}

	class Node implements Comparable<Node> {
		int dist,id;
		public Node(int dist, int i) {
			this.dist = dist;
			this.id = i;
		}
		public int compareTo(Node o) {
			return Integer.compare(dist, o.dist);
		}
	}
}
class IO extends PrintWriter {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	StringTokenizer st = null;
	public IO() { super (System.out); };
	public String next() {
		while( st== null || !st.hasMoreTokens()) {
			String s;
			try {
				s = br.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			if (s == null) return null;
			st = new StringTokenizer(s);
		}
		return st.nextToken();
	}
	public int nextInt() {
		return Integer.parseInt(next());
	}
}