AOJ2151 Brave Princess Revisited
問題リンク Brave Princess Revisited
- 解法
(町, 残金)をノードにしたダイクストラで解けます。
(i, c)の状態からは
お金を払わずに行く進み方
(残金が距離以上あるとき)お金を払って襲われる人数を0にして進む方法
の2通りがあります。
- ソース
import java.util.Arrays; import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner; //Brave Princess Revisited public class AOJ2151 { int[][] dist; void run(){ Scanner sc =new Scanner(System.in); int INF = 1<<29; for(;;){ int n = sc.nextInt(), m = sc.nextInt(), L = sc.nextInt(); if((n|m|L)==0)break; int[][] d = new int[n][n], e = new int[n][n]; for(int[]a:d)Arrays.fill(a, INF); for(int[]a:e)Arrays.fill(a, INF); while(m--!=0){ int s = sc.nextInt()-1, t = sc.nextInt()-1, D = sc.nextInt(), E = sc.nextInt(); d[s][t] = d[t][s] = D; e[s][t] = e[t][s] = E; } dist = new int[n][L+1]; for(int[]a:dist)Arrays.fill(a, INF); dist[0][L] = 0; PriorityQueue<int[]> q = new PriorityQueue<int[]>(n, new Comparator<int[]>() { public int compare(int[] o1, int[] o2) { return dist[o1[0]][o1[1]]-dist[o2[0]][o2[1]]; } }); q.add(new int[]{0, L}); int res = INF; while(!q.isEmpty()){ int[] a = q.poll(); int v = a[0], c = a[1]; if(v==n-1){ res = Math.min(res, dist[v][c]); continue; } for(int i=0;i<n;i++){ if(d[v][i]==INF)continue; int w = dist[v][c] + e[v][i]; if(w<dist[i][c]){ dist[i][c] = w; q.add(new int[]{i, c}); } if(d[v][i]<=c&&dist[v][c]<dist[i][c-d[v][i]]){ dist[i][c-d[v][i]] = dist[v][c]; q.add(new int[]{i, c-d[v][i]}); } } } System.out.println(res); } } public static void main(String[] args) { new AOJ2151().run(); } }