POJ 2349 Arctic Network

来源:互联网 发布:oracle sql调优技巧 编辑:程序博客网 时间:2024/05/22 11:39

题目大意:

        现有T个测例,每个测例中有N个岗哨和S个卫星频道(1 ≤ S ≤ 100,S < N ≤ 500),接下来给出N个点的坐标(Xi, Yi),其中0 ≤ Xi, Yi ≤ 10,000,拥有卫星频道的任意两个岗哨可以自由通信不受距离限制,由于卫星频道有限,因此没分配到卫星频道的岗哨之间通信必须通过无线电收发机,可以间接通信,比如A通过B和C通信,其中AB、BC的通信方式可以任意,但是无线电通信是受距离限制的,任意两点之间无线电通信距离不得超过D(D是浮点数),对于每个测例要求你设计一种最优的分配方案使得D最小,只要求输出最小的D,保留两位小数。

题目链接

注释代码:

/*                                   * Problem ID : POJ 2349 Arctic Network * Author     : Lirx.t.Una                                   * Language   : C++                       * Run Time   : 16 ms                                   * Run Memory : 1456 KB                                  */ #include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <queue>//结论:答案即为最小生成树的第S条边,重要结论!!最小生成树的第K大边的值唯一,不论最小生成树有多少种!!//距离平方的无穷大(大于10000^2 × 2)#defineINF2000000000//最大点数#defineMAXV500using namespace std;structPoint {intx, y;intPOW(int a) { return a * a; }intoperator^(Point &oth) { return POW( x - oth.x ) + POW( y - oth.y ); }};structNode {//Prim堆优化中的结点intu;//结点所代表的点intdp;//结点到当前未完成的生成树的当前最短距离Node(void) {}Node(int uu, int dd) : u(uu), dp(dd) {}bool//构造dp的小顶堆operator<(const Node &oth)const {return dp > oth.dp;}};Pointp[MAXV + 1];//点intw[MAXV + 1][MAXV + 1];//weight,计算任意两点之间的欧几里得距离的平方intans[MAXV + 1];//存储最后最小生成树中的所有边intdist[MAXV + 1];boolvist[MAXV + 1];doubleprim( int s, int n ) {inti;inte;//当前构造出的生成树的边数intu, v;Nodenode;priority_queue<Node>heap;memset(vist, 0, sizeof(vist));vist[1] = true;for ( i = 2; i <= n; i++ ) {dist[i] = w[1][i];heap.push(Node( i, dist[i] ));}e = 1;while (true) {//任意两点之间都有边所以必定有解while (true) {//必定有解node = heap.top();u = node.u;heap.pop();if ( !vist[u] ) {vist[u] = true;ans[e++] = node.dp;break;}}if ( e == n ) break;//构造完毕for ( v = 2; v <= n; v++ )if ( !vist[v] && w[u][v] < dist[v] ) {dist[v] = w[u][v];heap.push(Node( v, dist[v] ));//更优的结点入堆}}sort(ans, ans + e);//从小到大排return sqrt((double)ans[e - s]);//第e - s + 1为第S大边}intmain() {intt;//测例数ints, n;//卫星数,岗哨数inti, j;scanf("%d", &t);while ( t-- ) {scanf("%d%d", &s, &n);for ( i = 1; i <= n; i++ ) scanf("%d%d", &p[i].x, &p[i].y);for ( i = 1; i <= n; i++ )for ( j = i + 1; j <= n; j++ )w[i][j] = w[j][i] = p[i] ^ p[j];printf("%.2lf\n", prim( s, n ));}return 0;}
无注释代码:

#include <algorithm>#include <iostream>#include <cstring>#include <cstdio>#include <cmath>#include <queue>#defineINF2000000000#defineMAXV500using namespace std;structPoint {intx, y;intPOW(int a) { return a * a; }intoperator^(Point &oth) { return POW( x - oth.x ) + POW( y - oth.y ); }};structNode {intu;intdp;Node(void) {}Node(int uu, int dd) : u(uu), dp(dd) {}booloperator<(const Node &oth)const {return dp > oth.dp;}};Pointp[MAXV + 1];intw[MAXV + 1][MAXV + 1];intans[MAXV + 1];intdist[MAXV + 1];boolvist[MAXV + 1];doubleprim( int s, int n ) {inti;inte;intu, v;Nodenode;priority_queue<Node>heap;memset(vist, 0, sizeof(vist));vist[1] = true;for ( i = 2; i <= n; i++ ) {dist[i] = w[1][i];heap.push(Node( i, dist[i] ));}e = 1;while (true) {while (true) {node = heap.top();u = node.u;heap.pop();if ( !vist[u] ) {vist[u] = true;ans[e++] = node.dp;break;}}if ( e == n ) break;for ( v = 2; v <= n; v++ )if ( !vist[v] && w[u][v] < dist[v] ) {dist[v] = w[u][v];heap.push(Node( v, dist[v] ));}}sort(ans, ans + e);return sqrt((double)ans[e - s]);}intmain() {intt;ints, n;inti, j;scanf("%d", &t);while ( t-- ) {scanf("%d%d", &s, &n);for ( i = 1; i <= n; i++ ) scanf("%d%d", &p[i].x, &p[i].y);for ( i = 1; i <= n; i++ )for ( j = i + 1; j <= n; j++ )w[i][j] = w[j][i] = p[i] ^ p[j];printf("%.2lf\n", prim( s, n ));}return 0;}

0 0