#include #include #include #include #include #include const int infinity = 1 << 26; struct Connection{ std::string start, dest; int start_time, dest_time, cost; Connection(const std::string & s, int st, const std::string & d, int dt, int c) : start(s), start_time(st), dest(d), dest_time(dt), cost(c){} bool operator < (const Connection & c) const { if(start_time != c.start_time){return start_time < c.start_time;} return dest_time < c.dest_time; } }; int costOf(const std::vector > ×, int dest_time){ for(int i = times.size() - 1; i >= 0; i--){ if(times[i].first <= dest_time){ return times[i].second; } } return infinity; } //insert(table[d][k], dest, connections[i].dest_time, //connections[i].cost + table[s][k].second); void insert(std::vector > & times, int dest_time, int cost){ for(int i = times.size() - 1; i >= 0; i--){ if(times[i].first < dest_time){ if(cost < times[i].second){ times.insert(times.begin() + i + 1, std::make_pair(dest_time, cost)); } return; } else if(times[i].first == dest_time){ if(cost < times[i].second){times[i].second = cost;} return; } } times.insert(times.begin(), std::make_pair(dest_time, cost)); } std::map > >time_table[2]; void f(const std::vector & connections){ time_table[0].clear(); time_table[1].clear(); time_table[0]["Tokyo"].push_back(std::make_pair(480, 0)); time_table[1]["Hakodate"].push_back(std::make_pair(480, 0)); for(int i = 0; i < connections.size(); i++){ for(int j = 0; j < 2; j++){ std::map > > & table = time_table[j]; const std::string & s = connections[i].start; const std::string & d = connections[i].dest; for(int k = table[s].size() - 1; k >= 0; k--){ if(table[s][k].first <= connections[i].start_time){ insert(table[d], connections[i].dest_time, connections[i].cost + table[s][k].second); } } } } } int main(){ while(true){ int n; char start[100]; char dest[100]; int sh, sm, dh, dm, cost; scanf("%d", &n); if(n == 0){break;} std::vector connections; for(int i = 0; i < n; i++){ scanf("%s%d:%d%s%d:%d%d", &start, &sh, &sm, &dest, &dh, &dm, &cost); Connection c(start, sh * 60 + sm, dest, dh * 60 + dm, cost); connections.push_back(c); } std::map > >table[4]; std::sort(connections.begin(), connections.end()); f(connections); table[0] = time_table[0]; table[1] = time_table[1]; if(0) { std::string s = "Hakodate"; int index = 0 ; for(int i = 0; i < table[index][s].size(); i++){ printf("time = %02d:%02d, cost = %d\n", table[index][s][i].first / 60, table[index][s][i].first % 60, table[index][s][i].second); } } for(int i =0 ; i < connections.size(); i++){ std::swap(connections[i].start, connections[i].dest); if(0){//connections[i].start == "Tokyo"){ printf("from %02d:%02d to %02d:%02d\n", connections[i].start_time / 60, connections[i].start_time % 60, connections[i].dest_time / 60, connections[i].dest_time % 60); } int s_ = connections[i].start_time; int t_ = connections[i].dest_time; connections[i].start_time = 18 * 60 - (connections[i].start_time - 8 * 60); connections[i].dest_time = 18 * 60 - (connections[i].dest_time - 8 * 60); std::swap(connections[i].start_time, connections[i].dest_time); if(0){//connections[i].start == "Tokyo"){ printf("from %02d:%02d to %02d:%02d\n", connections[i].start_time / 60, connections[i].start_time % 60, connections[i].dest_time / 60, connections[i].dest_time % 60); } assert(s_ + connections[i].dest_time == 26 * 60); assert(t_ + connections[i].start_time == 26 * 60); } std::sort(connections.begin(), connections.end()); f(connections); table[2] = time_table[0]; table[3] = time_table[1]; typedef std::map > > T; int min_cost = infinity; for(int k = 0; k < 2; k++){ for(T::const_iterator i = table[k].begin(); i != table[k].end(); i++){ const std::string & meeting_town = i->first; for(int j = 0; j < i->second.size(); j++){ int time = i->second[j].first; int cost = i->second[j].second + costOf(table[1 - k][i->first], time) + costOf(table[2][i->first], 18 * 60 - (time + 30) + 8 * 60) + costOf(table[3][i->first], 18 * 60 - (time + 30) + 8 * 60); min_cost = std::min(cost, min_cost); if(0){//meeting_town == "Hakodate"){ printf("time = %02d:%02d\n", time / 60, time % 60); printf("%d, %d, %d, %d\n", i->second[j].second , costOf(table[1 - k][i->first], time), costOf(table[2][i->first], 18 * 60 - (time + 30) + 8 * 60), costOf(table[3][i->first], 18 * 60 - (time + 30) + 8 * 60)); } } } } if(min_cost == infinity){ printf("0\n"); }else{ printf("%d\n", min_cost); } } }