原题链接
可以在A点或S点分裂, 每次只能走一个分裂出来的点, 那么可以得知最后的答案一定是点与点之间相连的边权的总和.
边权我们可以通过bfs计算任意两个点之间的距离得到
(吐槽: 为什么越界也是WA...调了好久才发现)
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