Advertisement
jonathanasdf

2012WF G

Jun 22nd, 2013
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.83 KB | None | 0 0
  1. #include <iomanip>
  2. #include <cmath>
  3. #include <iostream>
  4. #include <cstring>
  5. #include <map>
  6. #include <vector>
  7. #include <set>
  8. using namespace std;
  9. typedef long long ll;
  10. typedef long double ld;
  11. const ld INF = 1e12;
  12. ll N, x[400], y[400], z[400], k[400];
  13. vector<int> adjl[400];
  14. int par[400]; ld cost[400][400];
  15. ld d[400];
  16. struct dcomp {
  17.   bool operator()(const int& a, const int& b) const {
  18.    return d[a] < d[b] || (d[a] == d[b] && a < b);
  19.   }
  20. };
  21.  
  22. int Find(int i) { return par[i]==i ? i : (par[i] = Find(par[i])); }
  23. void Union(int i, int j) { int pi = Find(i), pj = Find(j);
  24.   if (pi == pj) return;
  25.   k[pj] += k[pi];
  26.   for (int l=0; l < N; l++) {
  27.     if (Find(l) == pi)
  28.       cost[pj][l] = cost[l][pj] = 0;
  29.     else if (par[l] == l)
  30.       cost[pj][l] = cost[l][pj] = min(cost[pj][l], cost[pi][l]);
  31.   }
  32.   par[pi] = pj;
  33. }
  34.    
  35. int main() {
  36.     ios::sync_with_stdio(0);
  37.     int M, zz=1;
  38.     while(cin >> N >> M) {
  39.         map<int, vector<int> > heights;
  40.         for (int i=0; i < N; i++) {
  41.           cin >> x[i] >> y[i] >> z[i] >> k[i];
  42.           par[i] = i;
  43.           heights[z[i]].push_back(i);
  44.         }
  45.         for (int i=0; i < N; i++) adjl[i].clear();
  46.         for (int i=0; i < M; i++) {
  47.             int a, b; cin >> a >> b; a--; b--;
  48.             adjl[a].push_back(b);
  49.             adjl[b].push_back(a);
  50.         }
  51.         for (int i=0; i < N; i++) for (int j=0; j < N; j++) {
  52.           if (k[i] == 0 || k[j] == 0) cost[i][j] = 2*INF;
  53.           else cost[i][j] = sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])+(z[i]-z[j])*(z[i]-z[j])+0.L);
  54.         }
  55.  
  56.         ld best = INF;
  57.         for (map<int, vector<int> >::iterator it = heights.begin(); it != heights.end(); it++) {
  58.           int h = it->first; vector<int> &todo = it->second;
  59.           for (int i=0; i < todo.size(); i++)
  60.             for (int j=0; j < adjl[todo[i]].size(); j++)
  61.               if (z[adjl[todo[i]][j]] <= h)
  62.                 Union(todo[i], adjl[todo[i]][j]);
  63.  
  64.           if (h < z[0] || h < z[N-1]) continue;
  65.           for (int i=0; i < N; i++) d[i] = INF;
  66.           int st = Find(0);
  67.           d[st] = k[st]*0.5;
  68.           set<int, dcomp> q; q.insert(st);
  69.           while(q.size()) {
  70.             int next = *q.begin(); q.erase(q.begin());
  71.             for (int i=0; i < N; i++) if (par[i] == i && i != next && z[i] <= h) {
  72.               if (next != st && k[next] == 1) continue;
  73.               ld tcost = d[next] + cost[next][i] + k[i]*0.5 - 1;
  74.               if (tcost < d[i]) {
  75.                 q.erase(i);
  76.                 d[i] = tcost;
  77.                 q.insert(i);
  78.               }
  79.             }
  80.           }
  81.           best = min(best, d[Find(N-1)]);
  82.         }
  83.         cout << "Case " << zz++ << ": ";
  84.         if (best >= INF) cout << "impossible" << endl;
  85.         else cout << fixed << setprecision(4) << best << endl;
  86.     }
  87.     return 0;
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement