题目链接: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改了一下。