POJ3026 最小生成树

问题: POJ3026

分析:

采用BFS算出两两之间的距离,再用PRIM算法计算最小生成树。

AC代码:

  1 //Memory: 220K        Time: 32MS

  2 #include <iostream>

  3 #include <cstdio>

  4 #include <string>

  5 #include <cstring>

  6 #include <queue>

  7 

  8 using namespace std;

  9 

 10 const int maxn = 52;

 11 const int max_alien = 101;

 12 char maze[maxn][maxn];

 13 int m[maxn][maxn];

 14 int g[max_alien][max_alien];

 15 int vis[maxn][maxn];

 16 int v[max_alien + 1];

 17 int d[max_alien + 1];

 18 int alien;

 19 int test, x, y;

 20 int si[max_alien + 1], sj[max_alien + 1];

 21 int step[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};

 22 

 23 struct node

 24 {

 25     int i;

 26     int j;

 27     int d;

 28     void set(int ii, int jj)

 29     {

 30         i = ii;

 31         j = jj;

 32         d = 0;

 33     }

 34 }n1, n2;

 35 

 36 queue<struct node> q;

 37 

 38 void bfs(int num, int i, int j)

 39 {

 40     memset(vis, 0, sizeof(vis));

 41     int t = alien - num;

 42     while ( !q.empty() ) q.pop();

 43     n1.set(i, j);

 44     q.push(n1);

 45 

 46     while ( !q.empty() && t > 0 ){

 47         n1 = q.front();

 48         q.pop();

 49 

 50         for (int i = 0; i < 4; i++){

 51             n2.set(n1.i + step[i][0], n1.j + step[i][1]);

 52             /*if (n2.i < 0 || n2.j < 0 ||)*/

 53             if (maze[n2.i][n2.j] == '#' || vis[n2.i][n2.j]) continue;

 54             

 55             vis[n2.i][n2.j] = 1;

 56             n2.d = n1.d + 1;

 57 

 58             if (m[n2.i][n2.j] > num){

 59                 t--;

 60                 g[num][ m[n2.i][n2.j] ] = g[ m[n2.i][n2.j] ][num] = n2.d;

 61             }

 62 

 63             q.push(n2);

 64         }

 65     }

 66     

 67 }

 68 

 69 int prim()

 70 {

 71     memset(v, 0, sizeof(v));

 72     v[0] = 1;

 73     int ret = 0;

 74     for (int i = 1; i <= alien; i++)

 75         d[i] = g[0][i];

 76 

 77     for (int i = 0; i < alien; i++) {

 78 

 79         int _min = 3000, ix;

 80         for (int j = 1; j <= alien; j++) {

 81             if ( !v[j] && d[j] < _min){

 82                 _min = d[j];

 83                 ix = j;

 84             }

 85         }

 86         v[ix] = 1;

 87         ret += d[ix];

 88 

 89         for (int j = 1; j <= alien; j++){

 90             if (!v[j] && d[j] > g[ix][j])

 91                 d[j] = g[ix][j];

 92         }

 93     }

 94     return ret;

 95 }

 96 

 97 int main()

 98 {

 99     scanf("%d", &test);

100     while (test--){

101         memset(m, 0, sizeof(m));

102         scanf("%d%d", &x, &y);

103         gets(maze[0]);

104         alien = 0;

105         for (int i = 0; i < y; i++)

106             gets(maze[i]);

107         for (int i = 0; i < y; i++){

108             for (int j = 0; j < x; j++){

109                 if (maze[i][j] == 'S'){

110                     si[0] = i; 

111                     sj[0] = j;

112                 }

113                 else if (maze[i][j] == 'A') {

114                     m[i][j] = ++alien;

115                     si[alien] = i;

116                     sj[alien] = j;

117                 }

118             }

119         }

120 

121         memset(g, 0, sizeof(g));

122         for (int i = 0; i <= alien; i++){

123             bfs(i, si[i], sj[i]);

124         }

125 

126         int ans = prim();

127 

128         printf("%d\n", ans);

129     }

130     return 0;

131 }

 

 

你可能感兴趣的:(最小生成树)