/*------------------------------------------------------------------------------ * problem022.cc: Sim City (10.5.1) **----------------------------------------------------------------------------*/ /* Copyright (c) 2009 Peter Bui. All Rights Reserved. * * Peter Bui * **------------------------------------------------------------------------------ * Includes **----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include using namespace std; /*------------------------------------------------------------------------------ * Data Structures **----------------------------------------------------------------------------*/ typedef struct vertex Vertex; typedef struct edge Edge; typedef vector Graph; struct vertex { double x; double y; list edges; }; struct edge { int v; double weight; }; /*------------------------------------------------------------------------------ * Functions **----------------------------------------------------------------------------*/ static int read_vertices(Graph &g) { size_t nvertices, i; double x, y; Vertex *v; cin >> nvertices; for (i = 0; i < nvertices; i++) { cin >> x >> y; v = new Vertex(); v->x = x; v->y = y; g.push_back(v); } return (nvertices); } static bool edge_cmp(const Edge *e1, const Edge *e2) { return (e1->weight < e2->weight); } static void form_edges(Graph &g) { size_t v, n; Edge *e; for (v = 0; v < g.size(); v++) { for (n = 0; n < g.size(); n++) { if (n != v) { e = new Edge(); e->v = n; e->weight = sqrt(pow((g[v]->x - g[n]->x), 2) + pow((g[v]->y - g[n]->y), 2)); g[v]->edges.push_back(e); } } g[v]->edges.sort(edge_cmp); } } static double compute_minimum_spanning_tree(Graph &g) { int min_vertex; double min_weight, total_weight; set vertices; set::iterator vt; list::iterator et; total_weight = 0.0; vertices.insert(0); while (vertices.size() < g.size()) { min_weight = INFINITY; for (vt = vertices.begin(); vt != vertices.end(); vt++) { et = g[*vt]->edges.begin(); while (et != g[*vt]->edges.end()) { if (vertices.find((*et)->v) != vertices.end()) { et = g[*vt]->edges.erase(et); } else { if ((*et)->weight < min_weight) { min_weight = (*et)->weight; min_vertex = (*et)->v; } break; } } } total_weight += min_weight; vertices.insert(min_vertex); } return (total_weight); } static void clear_graph(Graph &g) { size_t v; list::iterator et; for (v = 0; v < g.size(); v++) { for (et = g[v]->edges.begin(); et != g[v]->edges.end(); et++) free(*et); free(g[v]); } g.clear(); } static void print_graph(Graph &g) { size_t v; list::iterator et; for (v = 0; v < g.size(); v++) { cout << g[v]->x << ' ' << g[v]->y << ':'; for (et = g[v]->edges.begin(); et != g[v]->edges.end(); et++) cout << " (" << (*et)->v << ", " << (*et)->weight << ")"; cout << endl; } } /*------------------------------------------------------------------------------ * Main Execution **----------------------------------------------------------------------------*/ int main(int argc, char* argv[]) { Graph g; while (read_vertices(g)) { form_edges(g); cout << fixed << setprecision(2) << compute_minimum_spanning_tree(g) << endl; clear_graph(g); } return (EXIT_SUCCESS); } /*------------------------------------------------------------------------------ * vim: sts=4 sw=4 ts=8 ft=cpp **----------------------------------------------------------------------------*/