poj2048&&zoj1751 Highways ——最小生成树入门题_Prim算法

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

题目大意:

  给定n个点的坐标。还有m对已经相连的点的编号。求连接这n个点的总权值最小的一棵生成树,输出还需要连接的点的编号。

题目思路:

  这道题目和以前做过的poj2421是一样的。这里采用了那篇博客里面的第一种方法。幸运的是,在poj上1A了。但是在zoj上,因为输入输出格式有一些不一样,卡了一下,到最后我也没明白“If no new highways need to be built (all towns are already connected), then the output should be created but it should be empty.” 这句话的含义,看书上的翻译是,如果不需要再建了,输出一个空行。可是,在poj上,输出空行与否都是可以过的。在zoj上,输出空行就WA了,就是因为这个错误……

poj代码:

 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 = 759;
23 double edge[MAX][MAX];
24 double lowcost[MAX];int nearvex[MAX];
25 int n, m;
26 typedef struct Point {
27   int x, y;
28 }Point;
29 Point point[MAX];
30 void prim(int u0) {
31   int i, j, k, v;double sum = 0;
32   for (i = 1; i <= n; ++i) {
33     lowcost[i] = edge[i][u0]; nearvex[i] = u0;
34   }
35   lowcost[u0] = 0; nearvex[u0] = -1;
36   for (i = 1; i < n; ++i) {
37     double min = 1.0*MAXN;int v = -1;
38     for (j = 1; j <= n; ++j) {
39       if (nearvex[j] != -1 && lowcost[j] < min) {
40         min = lowcost[j]; v = j;
41       }
42     }
43     if (v != -1){
44       if (lowcost[v] != 0) {
45         printf("%d %d\n", v, nearvex[v]);
46       }
47       sum += lowcost[v]; nearvex[v] = -1;
48       for (j = 1; j <= n; ++j) {
49         if (nearvex[j] != -1 && edge[v][j] < lowcost[j]) {
50           lowcost[j] = edge[v][j]; nearvex[j] = v;
51         }
52       }
53     }
54   }
55   if (sum == 0) printf("\n\n");
56 }
57 int main(void){
58 #ifndef ONLINE_JUDGE
59   freopen("poj1751.in", "r", stdin);
60 #endif
61   while (~scanf("%d", &n)) {
62     int i, j, k;
63     for (i = 1; i <= n; ++i) {
64       scanf("%d%d", &point[i].x, &point[i].y);
65     }
66     for (i = 1; i <= n; ++i) {
67       for (j = i+1; j <= n; ++j) {
68         int x1, y1; x1 = point[i].x-point[j].x;
69         y1 = point[i].y-point[j].y;
70         edge[j][i]=edge[i][j] = sqrt(pow(x1,2.0)+pow(y1,2.0));
71       }
72     }
73     scanf("%d", &m);
74     int a, b;
75     for (i = 1; i <= m; ++i) {
76       scanf("%d%d", &a, &b);
77       edge[a][b] = edge[b][a] = 0;
78     }
79     prim(1);
80   }
81 
82   return 0;
83 }

zoj代码:

 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 = 759;
23 double edge[MAX][MAX];
24 double lowcost[MAX];int nearvex[MAX];
25 int n, m;
26 typedef struct Point {
27   int x, y;
28 }Point;
29 Point point[MAX];
30 void prim(int u0) {
31   int i, j, k, v;double sum = 0;
32   for (i = 1; i <= n; ++i) {
33     lowcost[i] = edge[i][u0]; nearvex[i] = u0;
34   }
35   lowcost[u0] = 0; nearvex[u0] = -1;
36   for (i = 1; i < n; ++i) {
37     double min = 1.0*MAXN;int v = -1;
38     for (j = 1; j <= n; ++j) {
39       if (nearvex[j] != -1 && lowcost[j] < min) {
40         min = lowcost[j]; v = j;
41       }
42     }
43       if (lowcost[v] != 0) {
44         printf("%d %d\n", v, nearvex[v]);
45       }
46       sum += lowcost[v]; nearvex[v] = -1;
47       for (j = 1; j <= n; ++j) {
48         if (nearvex[j] != -1 && edge[v][j] < lowcost[j]) {
49           lowcost[j] = edge[v][j]; nearvex[j] = v;
50         }
51       }
52   }
53 }
54 int main(void){
55 #ifndef ONLINE_JUDGE
56   freopen("poj1751.in", "r", stdin);
57 #endif
58   int t; scanf("%d", &t);
59   while (t--) {
60     scanf("%d", &n);
61     int i, j, k;
62     for (i = 1; i <= n; ++i) {
63       scanf("%d%d", &point[i].x, &point[i].y);
64     }
65     for (i = 1; i <= n; ++i) {
66       for (j = i+1; j <= n; ++j) {
67         int x1, y1; x1 = point[i].x-point[j].x;
68         y1 = point[i].y-point[j].y;
69         edge[j][i]=edge[i][j] = (pow(x1,2.0)+pow(y1,2.0));
70       }
71     }
72     scanf("%d", &m);
73     int a, b;
74     for (i = 1; i <= m; ++i) {
75       scanf("%d%d", &a, &b);
76       edge[a][b] = edge[b][a] = 0;
77     }
78     prim(1);
79     if (t!=0) printf("\n");
80   }
81 
82   return 0;
83 }

  另外,还有一个小trick,因为不需要求最后的权值,我求的距离的作用是标记一下是不是到最后都不需要再建了,来决定是不是需要输出空行,虽然现在赶脚这个很多余……o(╯□╰)o 所以呢,注意到坐标范围是在10000以内,所以可以省掉sqrt()也不会溢出,就省去了开方的运算,直接用平方和表征距离,这样不就可以节省点儿时间了么……O(∩_∩)O哈哈~

posted on 2013-05-04 01:25  aries__liu  阅读(943)  评论(0编辑  收藏  举报