AOJ1162 Discrete Speed
問題リンク Discrete Speed
- 解法
(都市、進入時の速度)のノードのダイクストラで解けます。
出だしと、ゴール時の速度が1だという点に注意しましょう。
- ソース
import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner; //Descrete Speed public class AOJ1162 { public static int n; public static int m; public static int start; public static int goal; public static double[][][] dist; public static int[][] r; public static int[][] limit; public static double dijkstra(){ for(int i=0;i<=n;i++){ for(int j=0;j<=n;j++){ for(int k=0;k<31;k++) dist[i][j][k] = Integer.MAX_VALUE; } } dist[start][0][0] = 0; PriorityQueue<int[]> q = new PriorityQueue<int[]>(n, new Comparator<int[]>(){ public int compare(int[] a, int[] b) { return dist[a[0]][a[1]][a[2]]-dist[b[0]][b[1]][b[2]]<0?-1:dist[a[0]][a[1]][a[2]]-dist[b[0]][b[1]][b[2]]>0?1:0; } }); q.add(new int[]{start,0,0}); while(!q.isEmpty()){ int[] uu = q.poll(); int u = uu[0]; int pre = uu[1]; int v = uu[2]; if(u==goal&&v==1)return dist[u][pre][v]; for(int i=1;i<=n;i++){ if(i!=pre && r[u][i]!=0){ for(int x=v-1;x<=v+1;x++){ if(x<=0)continue; if(x>limit[u][i])continue; double nc = dist[u][pre][v] + r[u][i]*1.0/x; if(nc < dist[i][u][x]){ dist[i][u][x] = nc; q.add(new int[]{i, u, x}); } } } } } return -1; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(true){ n = sc.nextInt(); m = sc.nextInt(); if(n==0&&m==0)break; dist = new double[n+1][n+1][31]; r = new int[n+1][n+1]; limit = new int[n+1][n+1]; start = sc.nextInt(); goal = sc.nextInt(); for(int i=0;i<m;i++){ int u = sc.nextInt(); int v = sc.nextInt(); int d = sc.nextInt(); int l = sc.nextInt(); r[u][v] = r[v][u] = d; limit[u][v] = limit[v][u] = l; } double ans = dijkstra(); if(ans==-1)System.out.println("unreachable"); else System.out.printf("%.5f\n", ans); } } }