• poj2349 Arctic Network ——最小生成树入门题_Prim算法


    题目链接:http://poj.org/problem?id=2349 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=914

    题目大意:

      有一些炮台,如果这个炮台有卫星接收器,那么任意两个有卫星接收器的炮台可以通信,不受距离限制;否者,两个炮台之间只能通过对讲机通信,这是受距离限制的。要买一种对讲机,用在需要的炮台上,要求所有炮台两两之间可以直接或者间接通信,问要买通信距离至少为多少的对讲机可以满足要求。输入:S卫星接收器的数量,P炮台的数量,然后是P行,每行代表一个炮台的坐标。输出要求的对讲机的通信距离D。

    题目思路:

      题目意思比较难懂。关键是satellite channel的安放方法,注意,它是放在炮台上的,只要这个炮台上有这货,它就可以和任何也有这货的炮台通信。明白这一点,然后就简单了。有S个卫星接收器,那么就可以减少S-1个距离开销。要让D尽可能小,就让这S-1个距离开销最大,所以,想法就是,求这些点的最小生成树,然后把所选的边排序,第S大的边的权值就是所求。

      开始题意没搞懂。关键是“Any two outposts with a satellite channel can communicate via the satellite, regardless of their location.”这句话没有理解明白,也就是说,任何两个有卫星接收器的炮台都可通信!然后自己就把问题复杂化了……写的代码就很复杂了。。后来改了一下,就过了。。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cctype>
     6 #include <stack>
     7 #include <queue>
     8 #include <map>
     9 #include <set>
    10 #include <vector>
    11 #include <cmath>
    12 #include <algorithm>
    13 #define lson l, m, rt<<1
    14 #define rson m+1, r, rt<<1|1
    15 using namespace std;
    16 typedef long long int LL;
    17 const int MAXN =  0x3f3f3f3f;
    18 const int  MIN =  -0x3f3f3f3f;
    19 const double eps = 1e-9;
    20 const int dir[8][2] = {{0,1},{1,0},{0,-1},{-1,0},{-1,1},
    21   {1,1},{1,-1},{-1,-1}};
    22 const int MAX  = 500+10;
    23 int n, s, p;
    24 double edge[MAX][MAX];
    25 double lowcost[MAX];
    26 int nearvex[MAX];
    27 
    28 typedef struct Point {
    29   double x, y;
    30 }Point;
    31 
    32 typedef struct Vex {
    33   int i, j; double len;
    34   bool operator < (const Vex & other) const { // 不能写反了
    35     return len > other.len;
    36   }
    37 }Vex;
    38 
    39 map<int, bool> visit;
    40 Vex vex[MAX];
    41 Point point[MAX];
    42 
    43 void prim(int u0) {
    44   int v;  // 尼玛定义类型错了,我去……
    45   int cur = 0, i, j;
    46   visit.clear();
    47   for (i = 1; i <= p; ++i) {
    48     lowcost[i] = edge[u0][i]; nearvex[i] = u0;
    49   }
    50   lowcost[u0] = 0; nearvex[u0] = -1;
    51   for (i = 1; i < p; ++i) {
    52     v = -1; double min = MAXN*1.0;
    53     for (j = 1; j <= p; ++j) {
    54       if (lowcost[j] < min && nearvex[j] != -1) {
    55         min = lowcost[j]; v = j;
    56       }
    57     }
    58     if (v != -1) {
    59       nearvex[v] = -1;
    60       vex[cur].i = v; vex[cur].j = nearvex[v]; vex[cur].len = lowcost[v];
    61       cur++;
    62       for (j = 1; j <= p; ++j) {
    63         if (lowcost[j] > edge[v][j] && nearvex[j] != -1) {
    64           lowcost[j] = edge[v][j]; nearvex[j] = v;
    65         }
    66       }
    67     }
    68   }
    69   sort(vex, vex + cur); 
    70   printf("%.2f\n", vex[s-1].len); 
    71 }
    72 int main(void){
    73 #ifndef ONLINE_JUDGE
    74   freopen("poj2349.in", "r", stdin);
    75 #endif
    76   scanf("%d", &n);
    77   int i, j;// k;
    78   while (n--) {
    79     scanf("%d%d", &s, &p);
    80     for (i = 1; i <= p; ++i) {
    81       scanf("%lf%lf", &point[i].x, &point[i].y);
    82     }
    83     for (i = 1; i <= p; ++i) {
    84       for (j = i + 1; j <= p; ++j) {
    85         double x1=point[i].x,y1 =point[i].y,x2 = point[j].x, y2=point[j].y;
    86         double dis = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    87         edge[i][j] = edge[j][i] = dis;
    88       }
    89     }
    90     prim(1);
    91   }
    92 
    93   return 0;
    94 }

      唉,好复杂的代码……题意理解最重要了,这种题目应该考的就是题意……

      还有就是,结构体里面重载运算符的时候,貌似不能重载大于号?因为要逆序排序么,然后就把return改了一下。

  • 相关阅读:
    java前三章总结
    Java入门第二章
    java编程入门小结
    Java入门第二章
    java预习易错点
    计算机基础
    切换卡
    ajax
    水印4
    shuiyin3
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3058564.html
Copyright © 2020-2023  润新知