题意:
n个无线AP,有xy坐标属性,现在n个无线AP要桥接在一起不能断开连接,现在要求无线AP无线网络的覆盖半径最小是多少
分析:
看起来是像是最小生成树,这里是是求生成树中最长的边最短,就是最小瓶颈生成树。
可以证明最小瓶颈生成树就是最小生成树,详细看刘汝佳《算法入门经典训练指南》343页。
当时现场的时候,想试试最小生成树了,结果以为n方复杂度过不去,就没写,现在想起来,真是坑哦。
这题n有10000,所以不能直接建邻接矩阵,而是采用动态计算距离就行了。
比赛结束了随便一写就A了。。。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 6 using namespace std; 7 8 const int inf = 0x3f3f3f3f; 9 const int maxn = 10010; 10 11 double x[maxn]; 12 double y[maxn]; 13 14 int n; 15 16 double lowc[maxn]; 17 bool vis[maxn]; 18 19 double dis(double x1, double y1, double x2, double y2) { 20 return sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2)); 21 } 22 23 double prim() { 24 double res = 0; 25 memset(vis, 0, sizeof(vis)); 26 vis[0] = true; 27 for(int i = 1; i < n; i++)lowc[i] = dis(x[0], y[0], x[i], y[i]); 28 for(int i = 1; i < n; i++) { 29 double minc = inf; 30 int p = -1; 31 for(int j = 0; j < n; j++) { 32 if(!vis[j] && lowc[j] < minc) { 33 minc = lowc[j]; 34 p = j; 35 } 36 } 37 res = max(res, minc); 38 vis[p] = true; 39 for(int j = 0; j < n; j++) { 40 double d = dis(x[p], y[p], x[j], y[j]); 41 if(!vis[j] && lowc[j] > d) { 42 lowc[j] = d; 43 } 44 } 45 } 46 return res / 2; 47 } 48 49 50 int main() { 51 while(~scanf("%d", &n)) { 52 for(int i = 0; i < n; i++) { 53 scanf("%lf%lf", &x[i], &y[i]); 54 } 55 printf("%.9f\n", prim()); 56 57 } 58 59 return 0; 60 61 }