zoukankan      html  css  js  c++  java
  • 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哈哈~

  • 相关阅读:
    Android 编辑框(EditText)属性学习
    读书笔记 -《高效程序猿的45个习惯-敏捷开发修炼之道》
    Launcher3实现壁纸居中
    Trie树的常见应用大总结(面试+附代码实现)
    LeetCode Summary Ranges
    abap选择屏幕上的button
    SQLite Expert表分离和解决SQLite Expert删除表后大小不变的问题
    git push 失败
    动态限制EdiText仅仅能输入特定字符
    DateTime类常用技巧摘录
  • 原文地址:https://www.cnblogs.com/liuxueyang/p/3058657.html
Copyright © 2011-2022 走看看