// Gokuri #include #include #include #include #include #include #include #include #include #include using namespace std; #define FNAME "acm.txt" #define fin cin typedef int vert; struct cost_t { int offset, period; int length; }; typedef int len_t; typedef vector< pair > edges; typedef vector< edges > graph; class ToIntR { map mp; vector idmap; int id; public: ToIntR(int id = 0) : id(id) {} int operator[] (const string& s) { if(!mp.count(s)) idmap.push_back(s); return mp.count(s) ? mp[s] : (mp[s] = id++); } string id2value(int id) const { return idmap[id]; } size_t size() const { return idmap.size(); } }; string get_time(int tm) { static char buffer[32]; tm %= 24 * 60; int min = tm % 60; tm /= 60; bool pm = tm >= 12; if(pm) tm -= 12; if(!tm) tm += 12; sprintf(buffer, "%u:%02u %cM", tm, min, pm ? 'P' : 'A'); return string(buffer); } typedef pair cedge; int simulate(const graph& g, vert cur, int time, vert& ev) { priority_queue< cedge, vector, greater > Q; map shtstlen; Q.push(cedge(time, cur)); while(!Q.empty()) { cedge ce = Q.top(); Q.pop(); if(shtstlen.count(ce.second)) continue; shtstlen[ce.second] = ce.first; const edges ne = g[ce.second]; for(int i = 0; i < ne.size(); i++) { if(shtstlen.count(ne[i].first)) continue; const cost_t& c = ne[i].second; int lt = ((ce.first - c.offset) + c.period - 1) / c.period * c.period + c.offset + 15; lt += c.length; Q.push(cedge(lt, ne[i].first)); } } int mx = INT_MIN; for(map::const_iterator it = shtstlen.begin(); it != shtstlen.end(); ++it) //cout << cur << "-" << it->first << ": " << it->second << endl; if(mx < it->second) { mx = it->second; ev = it->first; } return mx; } void solve(const graph& g, const ToIntR& name_map) { int result_len = 0; pair result; pair result_time; for(int i = 0; i < g.size(); i++) { for(int j = 0; j < g[i].size(); j++) { if(i == g[i][j].first) abort(); const cost_t& c = g[i][j].second; int lt; if(c.period > 1) lt = c.offset + 1; else lt = 0; for(; lt < 24 * 60; lt += c.period) { vert ev; int endtime = simulate(g, i, lt, ev); if(endtime - lt > result_len || (endtime - lt == result_len && lt < result_time.first)) { result_len = endtime - lt; result = make_pair(i, ev); result_time = make_pair(lt, endtime); } } } } cout << "Longest trip: " << result_len << (result_len == 1 ? " minute" : " minutes") << endl; cout << "Origin " << name_map.id2value(result.first) << ' ' << get_time(result_time.first) << ", " << name_map.id2value(result.second) << ' ' << get_time(result_time.second) << "." << endl; } int main(void) { ifstream fin(FNAME); if (!fin) { return 1; } // INPUT HERE int ncase = 0; int n; while(cin >> n, n) { ToIntR name_map; graph g; while(n--) { string src, dst; int first, period, len; cin >> src >> dst >> first >> period >> len; // constr. graph if(name_map[src] >= g.size()) g.resize(name_map[src] + 1); if(name_map[dst] >= g.size()) g.resize(name_map[dst] + 1); cost_t c = {first, period, len}; g[name_map[src]].push_back(make_pair(name_map[dst], c)); } cout << "Input set " << ++ncase << ":" << endl; solve(g, name_map); cout << endl; } return 0; }