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改了一下。

posted on 2013-05-03 23:36  aries__liu  阅读(365)  评论(0编辑  收藏  举报