andmej / acm

My solutions for problems from the UVa Online Judge (Valladolid).

This URL has Read+Write access

acm / 10034 - Freckles / p10034.cpp
100644 66 lines (59 sloc) 1.779 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <cmath>
#include <map>
#include <queue>
#include <set>
 
using namespace std;
 
typedef pair<double, double> point;
//Gives a vector of adjacent nodes to a point
typedef map< point, vector<point> > graph;
//Edge of length "first" that arrives to point "second"
typedef pair<double, point> edge;
 
double euclidean(const point &a, const point &b){ return hypot(a.first-b.first, a.second-b.second);}
 
 
int main(){
  int casos;
  cin >> casos;
  while (casos--){
    graph g;
    int n;
    cin >> n;
    while (n--){
      double x,y;
      cin >> x >> y;
      point p(x,y);
      if (g.count(p) == 0){ //Si no está todavía
vector<point> v;
g[p] = v;
for (graph::iterator i = g.begin(); i != g.end(); ++i){
if ((*i).first != p){
(*i).second.push_back(p);
g[p].push_back((*i).first);
}
}
      }
    }
 
    set<point> visited;
    priority_queue<edge, vector<edge>, greater<edge> > q;
    //Each edge in q has got a length "first" and a point "second".
    //It means I can reach point "second" which is "first" meters away.
    //q has the closest reachable node on top (I may have already visited it!)
    q.push(edge(0.0, (*g.begin()).first));
    double totalDistance = 0.0;
    while (!q.empty()){
      edge nearest = q.top();
      q.pop();
      point actualNode = nearest.second;
      if (visited.count(actualNode) == 1) continue; //Ya habia visitado este
      totalDistance += nearest.first;
      visited.insert(actualNode);
      vector<point> neighbors = g[actualNode];
      for (int i=0; i<neighbors.size(); ++i){
point t = neighbors[i];
double dist = euclidean(actualNode, t);
q.push(edge(dist, t));
      }
    }
    printf("%.2f\n", totalDistance);
    if (casos > 0) cout << endl; //Endl between cases
  }
}