poj3026 Borg Maze(bfs+prim)

 

原题链接

 

可以在A点或S点分裂, 每次只能走一个分裂出来的点, 那么可以得知最后的答案一定是点与点之间相连的边权的总和.

边权我们可以通过bfs计算任意两个点之间的距离得到

 (吐槽: 为什么越界也是WA...调了好久才发现)

 

 

poj3026 Borg Maze(bfs+prim)
  1 #include <iostream>
  2 #include <cmath>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <string>
  7 #include <map>
  8 using namespace std;
  9 typedef long long ll;
 10 const int MAXN = 53, MAXP = 103, inf = 0x3f3f3f3f;
 11 
 12 struct node
 13 {
 14     int x;
 15     int y;
 16     int cnt;
 17     node(int x = 0, int y = 0, int cnt = 0) : x(x), y(y), cnt(cnt)
 18     {
 19     }
 20 };
 21 int g[MAXP][MAXP], dis[MAXP], ma[MAXN][MAXN];
 22 int n, m, ans, idx;
 23 bool vis[MAXN][MAXN], vis2[MAXP];
 24 int dx[4] = {1, 0, -1, 0};
 25 int dy[4] = {0, 1, 0, -1};
 26 string str;
 27 node p[MAXP];
 28 
 29 inline ll read()
 30 {
 31     int x = 0, f = 1;
 32     char ch = getchar();
 33     while (ch < '0' || ch > '9')
 34     {
 35         if (ch == '-')
 36             f = -1;
 37         ch = getchar();
 38     }
 39     while (ch >= '0' && ch <= '9')
 40     {
 41         x = x * 10 + ch - '0';
 42         ch = getchar();
 43     }
 44     return x * f;
 45 }
 46 
 47 bool check(int x, int y)
 48 {
 49     return x >= 1 && x <= m && y >= 1 && y <= n;
 50 }
 51 
 52 void bfs(node s, int pi)
 53 {
 54     memset(vis, 0, sizeof vis);
 55     queue<node> q;
 56     int cnt = 0;
 57     node cur;
 58     q.push(s);
 59     vis[s.x][s.y] = true;
 60     while (!q.empty())
 61     {
 62         cur = q.front();
 63         q.pop();
 64 
 65         int t = ma[cur.x][cur.y];
 66         if (t > 0)
 67         {
 68             g[pi][t] = g[t][pi] = min(g[pi][t], cur.cnt);
 69 
 70             ++cnt;
 71         }
 72         if (cnt == idx) //剪枝
 73             break;
 74 
 75         for (int i = 0, tx, ty; i < 4; ++i)
 76         {
 77             tx = cur.x + dx[i];
 78             ty = cur.y + dy[i];
 79             if (check(tx, ty) && ma[tx][ty] != -1 && !vis[tx][ty])
 80             {
 81                 q.push(node(tx, ty, cur.cnt + 1));
 82                 vis[tx][ty] = true;
 83             }
 84         }
 85     }
 86 }
 87 
 88 void prim()
 89 {
 90     memset(vis2, 0, sizeof vis2);
 91     memset(dis, 0x3f, sizeof dis);
 92 
 93     dis[1] = 0;
 94     for (int i = 0; i < idx; ++i)
 95     {
 96         int t = -1;
 97         for (int j = 1; j <= idx; ++j)
 98         {
 99             if (!vis2[j] && (t == -1 || dis[t] > dis[j]))
100                 t = j;
101         }
102 
103         if (i)
104         {
105             ans += dis[t];
106         }
107         vis2[t] = true;
108         for (int j = 1; j <= idx; ++j)
109         {
110             dis[j] = min(dis[j], g[t][j]);
111         }
112     }
113 }
114 
115 int main()
116 {
117     int T;
118     T = read();
119     while (T--)
120     {
121         ans = idx = 0;
122         memset(g, 0x3f, sizeof g);
123 
124         n = read();
125         m = read();
126         for (int i = 1; i <= m; ++i)
127         {
128             getline(cin, str);
129             for (int j = 0; j < n; ++j)
130             {
131                 if (str[j] == 'A' || str[j] == 'S')
132                 {
133                     ma[i][j + 1] = ++idx;
134                     p[idx] = node(i, j + 1);
135                 }
136                 else if (str[j] == '#')
137                     ma[i][j + 1] = -1;
138                 else
139                     ma[i][j + 1] = 0;
140             }
141         }
142 
143         for (int i = 1; i <= idx; ++i)
144             bfs(p[i], i);
145 
146         prim();
147         printf("%d\n", ans);
148     }
149 
150     return 0;
151 }
View Code

 

上一篇:概率论中的特征函数


下一篇:nRF24L01的发送性能优化