AOJ0244 Hot Spring Trip

問題リンク Hot Spring Trip

  • 解法

頂点を少し拡張してダイクストラするのが方針です。頂点を
0: まだ無料の権利を使っていない
1: 無料の権利を使い始めた
2: 無料の権利を使い終わった
という状態に拡張します。
状態0からは0か1
状態1からは2
状態2からは2
へ遷移します。

  • ソース
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

//Hot Spring Trip
public class AOJ0244 {

	int[][] e;
	int[][] dist;
	int INF = 1<<29;

	void run(){
		Scanner sc = new Scanner(System.in);
		for(;;){
			int n = sc.nextInt(), m = sc.nextInt();
			if((n|m)==0)break;
			e = new int[n][n];
			//0: can use 1:tochuu 2:cant use
			dist = new int[n][3];
			for(int[]ee:e)Arrays.fill(ee, INF);
			for(int[]d:dist)Arrays.fill(d, INF);
			while(m--!=0){
				int s = sc.nextInt()-1, t = sc.nextInt()-1, c = sc.nextInt();
				e[s][t] = e[t][s] = Math.min(e[s][t], c);
			}
			PriorityQueue<int[]> q = new PriorityQueue<int[]>(n, new Comparator<int[]>() {
				@Override
				public int compare(int[] o1, int[] o2) {
					return dist[o1[0]][o1[1]] - dist[o2[0]][o2[1]];
				}
			});
			dist[0][0] = 0;
			q.add(new int[]{0, 0});
			int res = INF;
			while(!q.isEmpty()){
				int[] V = q.poll();
				int p = V[0], s = V[1];
				if(p==n-1&&s!=1){
					res = Math.min(res, dist[p][s]);
				}
				if(s==0){
					for(int nx=0;nx<n;nx++){
						if(e[p][nx]==INF)continue;
						int w = dist[p][s] + e[p][nx];
						if(w < dist[nx][0]){
							dist[nx][0] = w; q.add(new int[]{nx, 0});
						}
						w = dist[p][s];
						if(w < dist[nx][1]){
							dist[nx][1] = w; q.add(new int[]{nx, 1});
						}
					}
				}
				else if(s==1){
					for(int nx=0;nx<n;nx++){
						if(e[p][nx]==INF)continue;
						int w = dist[p][s];
						if(w < dist[nx][2]){
							dist[nx][2] = w; q.add(new int[]{nx, 2});
						}
					}
				}
				else{
					for(int nx=0;nx<n;nx++){
						if(e[p][nx]==INF)continue;
						int w = dist[p][s] + e[p][nx];
						if(w < dist[nx][2]){
							dist[nx][2] = w; q.add(new int[]{nx, 2});
						}
					}
				}
			}
			System.out.println(res);
		}
	}

	public static void main(String[] args) {
		new AOJ0244().run();
	}
}