题目链接:
https://vjudge.net/problem/POJ-3026
题目大意:
在一个y行 x列的迷宫中,有可行走的通路空格’ ‘,不可行走的墙’#’,还有两种英文字母A和S,现在从S出发,要求用最短的路径L连接所有字母,输出这条路径L的总长度。
思路:
先BFS预处理出所有的字母之间的距离,然后用prim模板
超级坑的是这里得用gets()吃掉回车符,用getchar()会WA
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #include<stack> 8 #include<map> 9 #include<sstream> 10 using namespace std; 11 typedef long long ll; 12 typedef pair<int, int> Pair; 13 const int maxn = 1e2 + 10; 14 const int INF = 0x3f3f3f3f; 15 int dir[4][2] = {1,0,0,1,-1,0,0,-1}; 16 int T, n, m, x; 17 int Map[maxn][maxn];//存图 18 int lowcost[maxn], mst[maxn]; 19 void prim(int u, int n)//最小生成树起点 20 { 21 int sum_mst = 0;//最小生成树权值 22 for(int i = 0; i < n; i++)//初始化两个数组 23 { 24 lowcost[i] = Map[u][i]; 25 mst[i] = u; 26 } 27 mst[u] = -1;//设置成-1表示已经加入mst 28 for(int i = 0; i < n; i++) 29 { 30 int minn = INF; 31 int v = -1; 32 //在lowcost数组中寻找未加入mst的最小值 33 for(int j = 0; j < n; j++) 34 { 35 if(mst[j] != -1 && lowcost[j] < minn) 36 { 37 v = j; 38 minn = lowcost[j]; 39 } 40 } 41 if(v != -1)//v=-1表示未找到最小的边, 42 {//v表示当前距离mst最短的点 43 //printf("%d %d %d\n", mst[v], v, lowcost[v]);//输出路径 44 mst[v] = -1; 45 sum_mst += lowcost[v]; 46 for(int j = 0; j < n; j++)//更新最短边 47 { 48 if(mst[j] != -1 && lowcost[j] > Map[v][j]) 49 { 50 lowcost[j] = Map[v][j]; 51 mst[j] = v; 52 } 53 } 54 } 55 } 56 //printf("weight of mst is %d\n", sum_mst); 57 cout<<sum_mst<<endl; 58 } 59 string s[55]; 60 vector<Pair>a; 61 int vis[55][55]; 62 void bfs(int u, int x, int y)//BFS预处理,将x,y为起点进行遍历,求出每个点离当前点距离,更新出Map距离出来 63 { 64 queue<Pair>q; 65 q.push(Pair(x, y)); 66 67 memset(vis, -1, sizeof(vis)); 68 vis[x][y] = 0; 69 while(!q.empty()) 70 { 71 Pair now = q.front(); 72 q.pop(); 73 for(int i = 0; i < 4; i++) 74 { 75 int xx = now.first + dir[i][0]; 76 int yy = now.second + dir[i][1]; 77 if(xx >= 0 && xx < n && yy >= 0 && yy < m && s[xx][yy] != ‘#‘ && vis[xx][yy] == -1) 78 { 79 vis[xx][yy] = vis[now.first][now.second] + 1; 80 q.push(Pair(xx, yy)); 81 } 82 } 83 }/* 84 for(int i = 0; i < n; i++) 85 { 86 for(int j = 0; j < m; j++)cout<<vis[i][j]<<" "; 87 cout<<endl; 88 }*/ 89 for(int i = 0; i < a.size(); i++) 90 { 91 if(i == u)continue; 92 Map[u][i] = vis[a[i].first][a[i].second]; 93 } 94 } 95 int main() 96 { 97 cin >> T; 98 getchar(); 99 while(T--) 100 { 101 for(int i = 0; i < 55; i++)s[i].clear(); 102 char cc[5]; 103 cin >> m >> n; 104 gets(cc); 105 a.clear(); 106 for(int i = 0; i < n; i++) 107 { 108 getline(cin, s[i]); 109 for(int j = 0; j < m; j++) 110 if(s[i][j] == ‘S‘ || s[i][j] == ‘A‘) 111 a.push_back(Pair(i, j)); 112 } 113 for(int i = 0; i < a.size(); i++) 114 { 115 for(int j = 0; j < a.size(); j++) 116 { 117 if(i == j)Map[i][j] = 0; 118 else Map[i][j] = INF; 119 } 120 } 121 for(int i = 0; i < a.size(); i++) 122 bfs(i, a[i].first, a[i].second); 123 /*for(int i = 0; i < a.size(); i++) 124 { 125 for(int j = 0; j < a.size(); j++) 126 { 127 cout<<Map[i][j]<<" "; 128 } 129 cout<<endl; 130 }*/ 131 prim(0, a.size()); 132 } 133 return 0; 134 }