package com.interview.algorithms.dp;
import com.interview.basics.model.graph.searcher.IndexedPriorityQueue;
/**
* Created by stefanie on 2014/6/26.
*
* Given an undirected graph G having positive weights and N vertices.
* You start with having a sum of M money. For passing through a vertex i, you must pay S[i] money.
* If you don't have enough money - you can't pass through that vertex. Find the shortest path from vertex 1 to vertex N,
* respecting the above conditions; or state that such path doesn't exist. If there exist more than one path having the same length,
* then output the cheapest one. Restrictions: 1<N<=100 ; 0<=M<=100 ; for each i, 0<=S[i]<=100.
*/
public class C12_11_ShortestPaidPath {
static class Result{
int weight = Integer.MAX_VALUE;
int left = 0;
}
public static Result find(int[][] graph, int[] S, int M, int T){
int N = S.length;
boolean[] states = new boolean[N];
int[][] Min = new int[N][M + 1];
for(int i = 0; i < N; i++){
for(int j = 0; j <= M; j++){
Min[i][j] = Integer.MAX_VALUE;
}
}
Min[0][M] =0;
IndexedPriorityQueue<String, Integer> queue = new IndexedPriorityQueue<String, Integer>();
queue.add(0 + "-" + M,0);
while(!queue.isEmpty()){
String state = queue.poll();
int k = Integer.parseInt(state.split("-")[0]);
int l = Integer.parseInt(state.split("-")[1]);
if(!states[k]){
for(int p = 0; p < N; p++){
if(graph[k][p] != 0){
// If (l-S[p]>=0 AND Min[p][l-S[p]]>Min[k][l]+graph[k][p]) Then Min[p][l-S[p]]=Min[k][l]+graph[k][p]
int left = l-S[p];
if( left >= 0 && Min[p][left] > Min[k][l] + graph[k][p]){
Min[p][left] = Min[k][l] + graph[k][p];
queue.add(p + "-" + left, Min[p][left]);
states[k] = true;
}
}
}
}
}
Result r = new Result();
for(int j = M; j >= 0; j--){
if(Min[T][j] < r.weight){
r.weight = Min[T][j];
r.left = j;
}
}
return r;
}
}