Codeforces #55 (div2) E "Shortest Path"

問題:http://codeforces.com/problemset/problem/59/E

ラクティス.

都市の数と道路の数および通ってはいけない順番の数と,道路がつなぐ都市間と,通ってはいけない順番のリストが与えられる.都市番号を1-baseでナンバリングしたとき,都市番号1から都市番号nまでの最短経路を求める.ただし,その道のりの並びに通ってはいけない順番が含まれてはいけない.

ある都市から行ける都市すべてのうち,通ってはいけない順番が連続しないようにBFSしてゆくだけ.下記のコードはScannerを使わずにBufferedInputStreamを用いて行うと実行時間が1/3になる.

コード

import java.util.*;

public class E_ShortestPath {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int n = s.nextInt(), m = s.nextInt(), k = s.nextInt();
		List<List<Integer>> list = new ArrayList<List<Integer>>();
		for(int i = 0; i <= n; ++i){
			list.add(new ArrayList<Integer>());
		}
		for (int i = 0; i < m; ++i) {
			int u = s.nextInt(), v = s.nextInt();
			list.get(u).add(v);
			list.get(v).add(u);
		}
		Set<Is> tri = new HashSet<Is>();
		for (int i = 0; i < k; ++i) {
			tri.add(new Is( s.nextInt(), s.nextInt(), s.nextInt() ));
		}
		boolean[][] used = new boolean[n+1][n+1];
		int[][] prev = new int[n+1][n+1];
		Deque<int[]> q = new ArrayDeque<int[]>();
		list.get(0).add(1);
		q.add(new int[]{0, 1});
		prev[0][1] = -1;
		while(!q.isEmpty()){
			int[] p = q.poll();
			if(p[1] == n){
				Deque<Integer> result = new ArrayDeque<Integer>();
				for(int i = p[0], j = p[1]; i > -1;){
					result.push(j);
					int t = j;
					j = i;
					i = prev[i][t];
				}
				System.out.println(result.size()-1);
				System.out.println(result.toString().replaceAll("[\\[\\],]",""));
				return ;
			}
			for(int u : list.get(p[1])){
				if(!used[p[1]][u] && !tri.contains(new Is(p[0], p[1], u))){
					used[p[1]][u] = true;
					prev[p[1]][u] = p[0];
					q.add(new int[]{p[1], u});
				}
			}
		}
		System.out.println("-1");
	}
	static class Is{
		int[] is;
		public Is(int a, int b, int c) {
			is = new int[]{a, b, c};
		}
		@Override
		public int hashCode() {
			return Arrays.hashCode(is);
		}
		@Override
		public boolean equals(Object obj) {
			return Arrays.equals(is, ((Is)obj).is);
		}
	}
}