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 }
------------------------------------------------------------------
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。