题意:一群人在地图上走啊走 每走到一个 ‘S’ 或者 ‘A’ 就可以分开一次 最多分成四个小队(因为只有四个方向可以走),直到找到所有的‘A’,输出能找到所有‘A’的最小的步数。
注意,新的小队的移动次数从0开始计算。
显然,最小生成树算法。每一组相邻的'A'都可以看成是一个整体,这些独立的整体组成了一个图,在这个图上选取一个最小生成树,这颗最小生成树的边的权值之和即为答案。
此题新颖之处在于寻找最短的那条边。一提到最短边显然要用到BFS。
开始的时候以‘s’为BFS的起点出发 找到离它最近的那个‘A’,把这一组‘A’和‘s’看成一个整体,再以这个新的整体为BFS的起点出发,继续寻找下一组‘A’........知道找到所有的‘A’。
此题还有一个坑爹之处在于 输入行数和列数之后 要用gets() 吃掉多余的空格,而不是用getchar()........
Ac_code C++ 0MS 260KB
1 #include <iostream> 2 #include <algorithm> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <queue> 8 9 using namespace std; 10 11 char map[60][60]; 12 13 int vis[60][60]; 14 15 struct N 16 { 17 int r,c,ans; 18 }; 19 20 queue<N> q; 21 22 int jr[] = { 0,-1, 0, 1}; 23 int jc[] = {-1, 0, 1, 0}; 24 25 int Min; 26 27 void updata(N l,int r,int c) 28 { 29 while(!q.empty()) 30 q.pop(); 31 32 queue<N> tq; 33 N t,p; 34 35 tq.push(l); 36 37 vis[l.r][l.c] = 1; 38 39 while(!tq.empty()) 40 { 41 t = tq.front(); 42 tq.pop(); 43 for(int i = 0;i < 4; i++) 44 { 45 p.c = t.c + jc[i]; 46 p.r = t.r + jr[i]; 47 48 if(p.c >= 1 && p.c <= c && p.r >= 1 && p.r <= r && map[p.r][p.c] == 'A' && vis[p.r][p.c] == 0) 49 { 50 Min++; 51 52 vis[p.r][p.c] = 1; 53 54 p.ans = 0; 55 tq.push(p); 56 } 57 } 58 } 59 60 int i,j; 61 for(i = 1;i <= r; i++) 62 for(j = 1;j <= c; j++) 63 { 64 if(vis[i][j] == 1) 65 { 66 p.ans = 0; 67 p.r = i; 68 p.c = j; 69 q.push(p); 70 } 71 else if(vis[i][j] == 2) 72 { 73 vis[i][j] = 0; 74 } 75 } 76 } 77 78 void bfs(int sr,int sc,int r,int c)//bfs寻找最短路 79 { 80 while(!q.empty()) 81 q.pop(); 82 83 N t,p; 84 85 t.r = sr; 86 t.c = sc; 87 t.ans = 0; 88 89 vis[t.r][t.c] = 1; 90 91 int i; 92 93 q.push(t); 94 95 while(!q.empty()) 96 { 97 t = q.front(); 98 q.pop(); 99 for(i = 0;i < 4; i++) 100 { 101 p.c = t.c + jc[i]; 102 p.r = t.r + jr[i]; 103 p.ans = t.ans+1; 104 105 if(p.c >= 1 && p.c <= c && p.r >= 1 && p.r <= r && map[p.r][p.c] != '#' && vis[p.r][p.c] == 0) 106 { 107 vis[p.r][p.c] = 2; 108 109 q.push(p); 110 if(map[p.r][p.c] == 'A')//将此部分’A‘全都加到队列中 并标记。 111 { 112 Min += p.ans; 113 114 updata(p,r,c); 115 break; 116 } 117 } 118 } 119 } 120 } 121 122 int main() 123 { 124 int T; 125 126 int r,c,sr,sc; 127 128 int i,j; 129 char temp[51]; 130 cin>>T; 131 while(T--) 132 { 133 Min = 0; 134 cin>>c>>r; 135 gets(temp); 136 for(i = 1;i <= r; i++) 137 gets(map[i]+1); 138 for(i = 1;i <= r; i++) 139 for(j = 1;j <= c; j++) 140 { 141 if(map[i][j] == 'S') 142 { 143 sr = i; 144 sc = j; 145 break; 146 } 147 } 148 memset(vis,0,sizeof(vis)); 149 150 bfs(sr,sc,r,c); 151 cout<<Min<<endl; 152 } 153 return 0; 154 }