标签:
Description:
Input:
Output:
Sample Input:
2 6 5 ##### #A#A## # # A# #S ## ##### 7 7 ##### #AAA### # A# # S ### # # #AAA### #####
Sample Output:
8 11
题意:m*n的地图,‘A‘代表外星人,‘S‘代表查找的始点,现在要求从S出发找到所有的A,问最小的花费是多少,每一步的移动都花费1。
首先要BFS求出任意一个S或A之间的最小花费,然后构图,建立最小生成树,得到最小权值即最小花费。
#include<stdio.h> #include<queue> #include<string.h> #include<algorithm> using namespace std; const int INF=0x3f3f3f3f; const int N=110; struct node { int x, y, s; }; int G[N][N], dist[N], vis[N], no[N][N], m, n, ans; ///no数组存放的是第(i,j)位置是A或S的第几个序号,ans代表S和A的总个数 int dir[4][2] = { {1,0}, {-1,0}, {0,1}, {0,-1} }; char Map[N][N]; void Init() { int i, j; for (i = 0; i < N; i++) { dist[i] = INF; vis[i] = 0; for (j = 0; j < N; j++) { G[i][j] = INF; no[i][j] = 0; } G[i][i] = 0; } ans = 0; } void BFS(int x, int y, int z) { int i, visit[N][N], nx, ny; node now, next; queue<node>Q; memset(visit, 0, sizeof(visit)); now.x = x; now.y = y; now.s = 0; Q.push(now); visit[x][y] = 1; while (!Q.empty()) { now = Q.front(); Q.pop(); if (Map[now.x][now.y] == ‘S‘ || Map[now.x][now.y] == ‘A‘) G[z][no[now.x][now.y]] = G[no[now.x][now.y]][z] = now.s; ///遇到A和S,就保存要查询的节点到该点的最小距离(最小生成树是无向图) for (i = 0; i < 4; i++) { next.x = nx = now.x + dir[i][0]; next.y = ny = now.y + dir[i][1]; if (nx >= 0 && nx < m && ny >= 0 && ny < n && Map[nx][ny] != ‘#‘ && !visit[nx][ny]) { visit[nx][ny] = 1; next.s = now.s+1; Q.push(next); } } } } int Prim() { int i, j, Min, idex, num = 0; for (i = 1; i <= ans; i++) dist[i] = G[1][i]; vis[1] = 1; ///!!!易掉 for (i = 1; i < ans; i++) { Min = INF; for (j = 1; j <= ans; j++) { if (!vis[j] && dist[j] < Min) { Min = dist[j]; idex = j; } } vis[idex] = 1; num += Min; for (j = 1; j <= ans; j++) { if (dist[j] > G[idex][j] && !vis[j]) dist[j] = G[idex][j]; } } return num; } int main () { int T, i, j, num; scanf("%d", &T); while (T--) { Init(); scanf("%d%d ", &n, &m); for (i = 0; i < m; i++) gets(Map[i]); for (i = 0; i < m; i++) for (j = 0; j < n; j++) if (Map[i][j] == ‘S‘ || Map[i][j] == ‘A‘) no[i][j] = ++ans; ///将该位置节点的序号记录下来 for (i = 0; i < m; i++) for (j = 0; j < n; j++) if (Map[i][j] == ‘S‘ || Map[i][j] == ‘A‘) BFS(i, j, no[i][j]); ///每次遇到A和S就进行BFS,查找其与其他所有的S和A的距离 num = Prim(); printf("%d\n", num); } return 0; }
标签:
原文地址:http://www.cnblogs.com/syhandll/p/4728246.html