#include #include #include #include #include #include #include #define INFTY (INT_MAX/8) #define HAKODATE 0 #define TOKYO 1 using namespace std; struct train_t { int s_city, a_city; int s_time, a_time; int price; }; bool start_cmp(const train_t &x, const train_t &y) { return x.s_time < y.s_time; } bool arrival_cmp(const train_t &x, const train_t &y) { return y.a_time < x.a_time; } int n; train_t tr[2048]; /* The least required cost, when K left {Tokyo|Hakodate} at 08:00 until "time" for "city" */ /* city time */ int cost_from_tokyo [ 101][ 601]; int cost_from_hakodate[ 101][ 601]; /* The least required cost, when K left "city" at "time" until 18:00 for {Tokyo|Hakodate} */ /* city time */ int cost_for_tokyo [ 101][ 601]; int cost_for_hakodate [ 101][ 601]; int translate_time(string s) { int result = ((int)(s[0]-'0') * 10 + (int)(s[1]-'0')) * 60 + ((int)(s[3]-'0') * 10 + (int)(s[4]-'0')) - (60 * 8); if (result < 0 || result > 600) { return -1; } return result; } int input() { int price, new_n; string start_city, s_start_time, arrive_city, s_arrive_time; map city_dic; int start_time, arrive_time; city_dic.clear(); city_dic.insert(make_pair(string("Hakodate"), 0)); city_dic.insert(make_pair(string("Tokyo"), 1)); cin >> n; if (n == 0) { return 0; } new_n = 0; for (int i = 0; i < n; i++) { cin >> start_city >> s_start_time >> arrive_city >> s_arrive_time >> price; if (city_dic.find(start_city) == city_dic.end()) { city_dic.insert(make_pair(start_city, city_dic.size())); } if (city_dic.find(arrive_city) == city_dic.end()) { city_dic.insert(make_pair(arrive_city, city_dic.size())); } if (0 > (start_time = translate_time(s_start_time))) { continue; } if (0 > (arrive_time = translate_time(s_arrive_time))) { continue; } tr[new_n].s_city = city_dic[start_city]; tr[new_n].a_city = city_dic[arrive_city]; tr[new_n].s_time = start_time; tr[new_n].a_time = arrive_time; tr[new_n].price = price; new_n++; } n = new_n; return 1; } void init_table() { for (int i = 0; i < 101; i++) { for (int j = 0; j < 601; j++) { cost_from_tokyo[i][j] = cost_from_hakodate[i][j] = cost_for_tokyo[i][j] = cost_for_hakodate[i][j] = INFTY; } } } void calc_cost() { int i; init_table(); i = 0; cost_from_tokyo[TOKYO][0] = cost_from_hakodate[HAKODATE][0] = 0; sort(&tr[0], &tr[n], start_cmp); for (int t = 0; t < 600; t++) { for (int c = 0; c < 100; c++) { if (cost_from_tokyo[c][t+1] > cost_from_tokyo[c][t]) { cost_from_tokyo[c][t+1] = cost_from_tokyo[c][t]; } if (cost_from_hakodate[c][t+1] > cost_from_hakodate[c][t]) { cost_from_hakodate[c][t+1] = cost_from_hakodate[c][t]; } } while (tr[i].s_time == t) { if (cost_from_tokyo[tr[i].a_city][tr[i].a_time] > cost_from_tokyo[tr[i].s_city][tr[i].s_time] + tr[i].price) { cost_from_tokyo[tr[i].a_city][tr[i].a_time] = cost_from_tokyo[tr[i].s_city][tr[i].s_time] + tr[i].price; } if (cost_from_hakodate[tr[i].a_city][tr[i].a_time] > cost_from_hakodate[tr[i].s_city][tr[i].s_time] + tr[i].price) { cost_from_hakodate[tr[i].a_city][tr[i].a_time] = cost_from_hakodate[tr[i].s_city][tr[i].s_time] + tr[i].price; } i++; } } i = 0; cost_for_tokyo[TOKYO][600] = cost_for_hakodate[HAKODATE][600] = 0; sort(&tr[0], &tr[n], arrival_cmp); for (int t = 600; t > 0; t--) { for (int c = 0; c < 100; c++) { if (cost_for_tokyo[c][t-1] > cost_for_tokyo[c][t]) { cost_for_tokyo[c][t-1] = cost_for_tokyo[c][t]; } if (cost_for_hakodate[c][t-1] > cost_for_hakodate[c][t]) { cost_for_hakodate[c][t-1] = cost_for_hakodate[c][t]; } } while (tr[i].a_time == t) { if (cost_for_tokyo[tr[i].s_city][tr[i].s_time] > cost_for_tokyo[tr[i].a_city][tr[i].a_time] + tr[i].price) { cost_for_tokyo[tr[i].s_city][tr[i].s_time] = cost_for_tokyo[tr[i].a_city][tr[i].a_time] + tr[i].price; } if (cost_for_hakodate[tr[i].s_city][tr[i].s_time] > cost_for_hakodate[tr[i].a_city][tr[i].a_time] + tr[i].price) { cost_for_hakodate[tr[i].s_city][tr[i].s_time] = cost_for_hakodate[tr[i].a_city][tr[i].a_time] + tr[i].price; } i++; } } } int search_best() { int best = INFTY; for (int t = 0; t <= (600-30); t++) { for (int c = 0; c < 100; c++) { int sum = cost_from_tokyo[c][t] + cost_from_hakodate[c][t] + cost_for_tokyo[c][t+30] + cost_for_hakodate[c][t+30]; if (best > sum) { best = sum; } } } if (best == INFTY) { return 0; } else { return best; } } int main() { while (input()) { calc_cost(); cout << search_best() << endl; } return 0; }