/* Subject: Contest submission for problem #3, file 3.cc */ /* cs188-ah@imail.EECS.Berkeley.EDU */ /* Wed Sep 17 19:36:43 PDT 2003 */ /*___CONTEST_SUBMISSION___ cs188-ah 3 */ //Estimated time: 1 hour //Time 2 hour 30 minutes //Hardest part was implementing djikstra's algorithm correctly using vectors galore //Update: I reread the specs and notice the case of if there are multiple short paths //then the Borogove chooses the path the lower room number. My version //assumes only 1 shortest path, so it will fail there. #include #include #include #include const int MAX_ROOMS = 1024; using namespace std; int distances[MAX_ROOMS][MAX_ROOMS]; map < int, vector*> edges; int num_room; //djikstra's algoirithm variables vector d; vector prev; set gq; int v, u; //djikstra's algorithm vector* run(int s, int t); int relax(int u, int v, int w); //shortest distance between room s and t int dist(int s, int t); int main(int argc, char* argv[]) { vector* path; cin >> num_room; for(int ii = 0; ii < num_room; ii++) edges[ii] = new vector; gq.clear(); while(!cin.eof()) { int n1, n2 , d; cin >> n1 >> n2 >> d; distances[n1][n2] = d; distances[n2][n1] = d; if (edges[n1] == NULL) edges[n1] = new vector; if (edges[n2] == NULL) edges[n2] = new vector; edges[n1]->push_back(n2); edges[n2]->push_back(n1); gq.insert(n1); gq.insert(n2); } bool escapes = true; path = run(1, 0); for(int ii = 0; ii < path->size(); ii++) // borogove snark if (dist(1, (*path)[ii]) > 2*dist(2, (*path)[ii])) { cout << "Snark eats" << endl; escapes = false; break; } if(escapes) cout << "Borogove escapes" << endl; delete path; for(int ii = 0; ii < num_room; ii++) delete edges[ii]; } vector* run(int start, int goal) { d = vector(MAX_ROOMS, INT_MAX); prev = vector(num_room, INT_MAX); d[start] = 0; vector* path = new vector(0); vector q(num_room); int ii = 0; for(set::iterator si = gq.begin(); si != gq.end() && ii < num_room; si++, ii++) q[ii] = *si; while (q.size() != 0) { // extracts min , should probably use priority queue int low = d[q[0]]; int qi = 0; for(int ii = 0; ii < q.size(); ii++) if (d[q[ii]] < low) { low = d[q[ii]]; qi = ii; } u = q[qi]; q.erase(q.begin()+qi); for(int ii = 0; ii < edges[u]->size(); ii++) { v = (*edges[u])[ii]; relax(u, v, distances[u][v]); } } int end = goal; for(;;) { path->push_back(end); if (end == start) break; end = prev[end]; } reverse(path->begin(), path->end()); return path; } int dist(int start, int goal) { vector* path = run(start, goal); int dd = 0; for(int ii = 0; ii < path->size()-1; ii++) dd += distances[(*path)[ii]][(*path)[ii + 1]]; delete path; return dd; } int relax(int u, int v, int w) { if (d[v] > (d[u] + w)) { d[v] = d[u] + w; prev[v] = u; } }