POJ 2349 Arctic Network

题意:有p个无限电波发射点,他们每个的有效范围都是d,即能与半径为d的圆内的其他无线电波点传递信息。同时,这些无线电波点之中可以选择s个点建立通讯卫星,建立了通讯卫星的之后的点都能传递信息。给出p,s和每个无线电波发射点的坐标,求d的最小值。

解法:此处就是做一遍最小生成树,输出树的所有边中第s大的那个的值。具体证明过程见[小结论]使生成树的第k大的边最小的边的求法

tag:MST

  1 /*
  2  * Author:  Plumrain
  3  * Created Time:  2013-12-02 23:36
  4  * File Name: G-POJ-2349.cpp
  5  */
  6 #include <iostream>
  7 #include <cstdio>
  8 #include <cstring>
  9 #include <cmath>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <queue>
 13 
 14 using namespace std;
 15 
 16 #define CLR(x) memset(x, 0, sizeof(x))
 17 #define PB push_back
 18 const double eps = 1e-8;
 19 const int maxint = 1147483647;
 20 typedef pair<int, double> pid;
 21 struct pnt{double x, y;};
 22 
 23 pnt p[505];
 24 double d[505];
 25 bool v[505];
 26 
 27 struct cmp{
 28     bool operator() (pid a, pid b){
 29         return a.second > b.second + eps;
 30     }
 31 };
 32 
 33 bool cmp2(double x, double y)
 34 {
 35     return x > y + eps;
 36 }
 37 
 38 double dis(pnt p1, pnt p2)
 39 {
 40     return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
 41 }
 42 
 43 void init(int& s, int& n)
 44 {
 45     scanf ("%d%d", &s, &n);
 46     for (int i = 0; i < n; ++ i)
 47         scanf ("%lf%lf", &p[i].x, &p[i].y);
 48 }
 49 
 50 double prim(int n, int s)
 51 {
 52     vector<double> ret; ret.clear();
 53     priority_queue<pid, vector<pid>, cmp> q;
 54     while (!q.empty()) q.pop();
 55 
 56     CLR (v);
 57     v[0] = 1; d[0] = 0;
 58     for (int i = 1; i < n; ++ i){
 59         d[i] = dis(p[i], p[0]);
 60         pid tmp;
 61         tmp.first = i; tmp.second = d[i];
 62         q.push (tmp);
 63     }
 64 
 65     for (int i = 0; i < n-1; ++ i){
 66         if (q.empty()) break;
 67         pid t = q.top(); q.pop();
 68         while (v[t.first] && !q.empty()){
 69             t = q.top(); q.pop();
 70         }
 71         if (v[t.first]) break;
 72 
 73         v[t.first] = 1; ret.PB (t.second);
 74         for (int j = 1; j < n; ++ j) if (!v[j]){
 75             double tmp = dis(p[t.first], p[j]);
 76             if (tmp < d[j]){
 77                 d[j] = tmp;
 78                 pid x;
 79                 x.first = j; x.second = tmp;
 80                 q.push (x);
 81             }
 82         }
 83     }
 84 
 85     sort(ret.begin(), ret.end(), cmp2);
 86     return ret[s-1];
 87 }
 88 
 89 int main()
 90 {
 91     int T;
 92     scanf ("%d", &T);
 93     while (T--){
 94         int s, n;
 95         init(s, n);
 96         double ans = prim(n, s);
 97         printf ("%.2f\n", ans);
 98     }
 99     return 0;
100 }
View Code

 

posted @ 2013-12-03 02:29  Plumrain  阅读(260)  评论(0编辑  收藏  举报