• ACM/ICPC 之 四道MST-Prim解法(POJ1258-POJ1751-POJ2349-POJ3026)


      四道MST,适合Prim解法,也可以作为MST练习题。

      题意包括在代码中。


    POJ1258-Agri Net

      水题

     1 //Prim-没什么好说的
     2 //接受一个邻接矩阵,求MST
     3 //Time:0Ms    Memory:220K
     4 #include<iostream>
     5 #include<cstring>
     6 #include<cstdio>
     7 #include<algorithm>
     8 using namespace std;
     9 #define MAX 105
    10 #define INF 0x3f3f3f3f
    11 int n, m;
    12 int d[MAX][MAX];
    13 int lowcost[MAX];
    14 bool v[MAX];
    15 void prim()
    16 {
    17     int minroad = 0;
    18     memset(v, false, sizeof(v));
    19     v[0] = true;
    20     for (int i = 1; i < n; i++)
    21         lowcost[i] = d[i][0];
    22     for (int i = 1; i < n; i++)
    23     {
    24         double mind = INF;
    25         int k;
    26         for (int j = 1; j < n; j++)
    27         {
    28             if (!v[j] && mind > lowcost[j])
    29             {
    30                 mind = lowcost[j];
    31                 k = j;
    32             }
    33         }
    34     
    35         minroad += lowcost[k];
    36         v[k] = true;
    37         for (int j = 1; j < n; j++)
    38             if (!v[j])    lowcost[j] = min(d[k][j], lowcost[j]);
    39     }
    40     printf("%d
    ", minroad);
    41 }
    42 int main()
    43 {
    44     while (scanf("%d", &n) != EOF)
    45     {
    46         for (int i = 0; i < n; i++)
    47             for (int j = 0; j < n; j++)
    48                 scanf("%d", &d[i][j]);
    49         prim();
    50     }
    51     return 0;
    52 }

    POJ1751(ZOJ2048)-Highways

     1 //Prim-好题
     2 //ZOJ2048-POJ1751
     3 //ZOJ中多组样例,两个样例间有一个空格(否则会WA)
     4 //需要记录上一个节点-注意内存限制在10^4K内
     5 //有M个城市已经有通路,输出让N个城市生成最短通路的各边,Special Judge-输出次序不定
     6 //Time:94Ms    Memory:4648K
     7 #include<iostream>
     8 #include<cstring>
     9 #include<cstdio>
    10 #include<cmath>
    11 #include<algorithm>
    12 using namespace std;
    13 
    14 #define MAX 755
    15 #define INF 0x3f3f3f3f
    16 #define POW2(x) ((x)*(x))
    17 #define DIS(i,j) (sqrt(POW2(p[i][0] - p[j][0]) + POW2(p[i][1] - p[j][1])))
    18 
    19 int n, m;
    20 double p[MAX][2];
    21 int fa[MAX];    //记录上一个顶点
    22 double d[MAX][MAX];
    23 double lowcost[MAX];
    24 bool v[MAX];
    25 
    26 void prim()
    27 {
    28     memset(v, false, sizeof(v));
    29     v[1] = true;
    30     for (int i = 2; i <= n; i++)
    31     {
    32         lowcost[i] = d[i][1];
    33         fa[i] = 1;
    34     }
    35     for (int i = 2; i <= n; i++)
    36     {
    37         double mind = INF;
    38         int k;
    39         for (int j = 2; j <= n; j++)
    40         {
    41             if (!v[j] && mind > lowcost[j])
    42             {
    43                 mind = lowcost[j];
    44                 k = j;
    45             }
    46         }
    47         if (mind > 1e-5)
    48             printf("%d %d
    ", fa[k], k);
    49     
    50         v[k] = true;
    51         for (int j = 2; j <= n; j++)
    52         {
    53             if (!v[j] && lowcost[j] > d[k][j])
    54             {
    55                 lowcost[j] = d[k][j];
    56                 fa[j] = k;
    57             }
    58         }
    59     }
    60 }
    61 
    62 int main()
    63 {
    64     scanf("%d", &n);
    65     for (int i = 1; i <= n; i++)
    66     {
    67         scanf("%lf%lf", &p[i][0], &p[i][1]);
    68         for (int j = 1; j < i; j++)
    69             d[i][j] = d[j][i] = DIS(i, j);
    70     }
    71     scanf("%d", &m);
    72     for (int i = 0; i < m; i++)
    73     {
    74         int v1, v2;
    75         scanf("%d%d", &v1, &v2);
    76         d[v1][v2] = d[v2][v1] = 0;
    77     }
    78     prim();
    79     return 0;
    80 }

    POJ2349(ZOJ1914)-Arctic Network

     1 //Prim
     2 //POJ2349-ZOJ1914
     3 //有n个前哨可以通过卫星通信(无距离限制),总共m个前哨,相互通信可以通过无线电通信(有距离限制),求所需无线电信号最短距离
     4 //定理:如果去掉所有权值大于d的边后,最小生成树被分割成为k个连通支,图也被分割成为k个连通支(可尝试证明)
     5 //Time:47Ms    Memory:2164K
     6 #include<iostream>
     7 #include<cstring>
     8 #include<cstdio>
     9 #include<cmath>
    10 #include<algorithm>
    11 using namespace std;
    12 
    13 #define MAX 501
    14 #define INF 0x3f3f3f3f
    15 #define POW2(x) ((x)*(x))
    16 #define DIS(i,j) (sqrt(POW2(p[i][0] - p[j][0]) + POW2(p[i][1] - p[j][1])))
    17 
    18 int n, m;
    19 double p[MAX][2];    //point
    20 double d[MAX][MAX];    //distance
    21 double lowcost[MAX];
    22 bool v[MAX];
    23 
    24 void prim()
    25 {
    26     memset(lowcost, 0, sizeof(lowcost));
    27     memset(v, false, sizeof(v));
    28     v[0] = true;
    29     for (int i = 1; i < m; i++)
    30         lowcost[i] = d[i][0];
    31     for (int i = 1; i < m; i++)
    32     {
    33         int mind = INF;
    34         int k;
    35         for (int j = 1; j < m; j++)
    36         {
    37             if (!v[j] && mind > lowcost[j])
    38             {
    39                 mind = lowcost[j];
    40                 k = j;
    41             }
    42         }
    43         v[k] = true;
    44         for (int j = 1; j < m; j++)
    45             if(!v[j]) lowcost[j] = min(d[k][j], lowcost[j]);
    46     }
    47 }
    48 
    49 int main()
    50 {
    51     int T;
    52     scanf("%d", &T);
    53     while (T--)
    54     {
    55         scanf("%d%d", &n, &m);
    56         for (int i = 0; i < m; i++)
    57         {
    58             scanf("%lf%lf", &p[i][0], &p[i][1]);
    59             for (int j = 0; j < i; j++)
    60                 d[i][j] = d[j][i] = DIS(i, j);
    61         }
    62         
    63         prim();
    64         sort(lowcost, lowcost + m);
    65         printf("%.2lf
    ", lowcost[m - n]);
    66         //G++需要使用printf("%.2f
    ", lowcost[m-n]);
    67         //原因查了半天,好像是因为新版GCC标准中将%f和%lf合并为%f的意思
    68     }
    69     return 0;
    70 }

    POJ3026-Borg Maze

      1 //Prim+BFS
      2 //总是心想着要创造一个新算法,结果越想越麻烦...
      3 //保险做法:找出每个点间的距离,再进行Prim
      4 //Time:79Ms    Memory:292K
      5 #include<iostream>
      6 #include<cstring>
      7 #include<cstdio>
      8 #include<queue>
      9 #include<algorithm>
     10 using namespace std;
     11 
     12 #define MAX 125        //MAX 50的话会RE或WA(博主在55RE,在100WA)
     13 
     14 struct Point{
     15     int x, y;
     16     int step;
     17 }p;
     18 
     19 int r, c;
     20 char board[MAX][MAX];
     21 int d[MAX][MAX];
     22 int num[MAX][MAX], cnt;
     23 int lowcost[MAX];
     24 bool v[MAX][MAX];
     25 int mov[4][2] = { {1,0}, {-1,0}, {0,1}, {0,-1} };
     26 
     27 void bfs(Point p)
     28 {
     29     memset(v, false, sizeof(v));
     30     v[p.x][p.y] = true;
     31     int np = num[p.x][p.y];
     32     queue<Point> q;
     33     p.step = 0;
     34     q.push(p);
     35     while (!q.empty())
     36     {
     37         Point cur = q.front();
     38         q.pop();
     39         for (int i = 0; i < 4; i++)
     40         {
     41             Point t = cur;
     42             t.x += mov[i][0];
     43             t.y += mov[i][1];
     44             if (t.x > 0 && t.y > 0 && t.x < r && t.y < c && !v[t.x][t.y])
     45             {
     46                 if (board[t.x][t.y] == '#')    continue;
     47                 int nt = num[t.x][t.y];
     48                 t.step++;
     49                 v[t.x][t.y] = true;
     50                 if (board[t.x][t.y] == 'A' || board[t.x][t.y] == 'S')
     51                     d[nt][np] = t.step;
     52                 q.push(t);
     53             }
     54         }
     55     }
     56 }
     57 
     58 void prim()
     59 {
     60     int v[MAX];
     61     memset(v, false, sizeof(v));
     62     memset(lowcost, 0x3f, sizeof(lowcost));
     63     v[0] = true;
     64     for (int i = 1; i < cnt; i++)
     65         lowcost[i] = d[i][0];
     66     
     67     int minv = 0;
     68     for (int i = 1; i < cnt; i++)
     69     {
     70         int mind = 0x3f3f3f3f;
     71         int k;
     72         for (int j = 1; j < cnt; j++)
     73         {
     74             if (!v[j] && mind > lowcost[j])
     75             {
     76                 mind = lowcost[j];
     77                 k = j;
     78             }
     79         }
     80         minv += mind;
     81         v[k] = true;
     82         for (int j = 1; j < cnt; j++)
     83             if (!v[j]) lowcost[j] = min(lowcost[j], d[k][j]);
     84     }
     85     printf("%d
    ", minv);
     86 }
     87 
     88 int main()
     89 {
     90     int T;
     91     scanf("%d", &T);
     92     while (T--)
     93     {
     94         cnt = 0;
     95         scanf("%d%d", &c, &r);
     96         gets_s(board[0]);
     97         for (int i = 0; i < r; i++)
     98         {
     99             gets_s(board[i], MAX);
    100             for (int j = 0; j < c; j++)
    101                 if (board[i][j] == 'S' || board[i][j] == 'A')
    102                     num[i][j] = cnt++;
    103         }
    104         for (int i = 0; i < r; i++)
    105             for (int j = 0; j < c;j++)
    106                 if (board[i][j] == 'S' || board[i][j] == 'A')
    107                 {
    108                     p.x = i; p.y = j;
    109                     bfs(p);
    110                 }
    111         prim();
    112     }
    113     return 0;
    114 }
    他坐在湖边,望向天空,她坐在对岸,盯着湖面
  • 相关阅读:
    CTS2019 题解
    CTS2019 & APIO2019 游记
    WF 2019
    BZOJ 2560 及其加强
    UOJ 191
    SCOI2019 退役记
    HTML5 本地存储
    js数据类型
    解析json成javascript对象
    http状态码;
  • 原文地址:https://www.cnblogs.com/Inkblots/p/5380599.html
Copyright © 2020-2023  润新知