POJ 3026 Borg Maze (Prim+bfs)

版权声明:听说这里让写版权声明~~~ https://blog.csdn.net/m0_37691414/article/details/82114810

解析:给定一个迷宫,bfs求字母间的距离即边的权值,再prim求最小生成树的权值和即为本题答案。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 105;
int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
int e[N][N], dis[N], b[N][N];
char map[N][N];
bool book[N][N], visit[N];
struct node{
	int x, y, step;
};
int n, m;
void bfs(int s, int x, int y){
	memset(book, false, sizeof(book));
	node p, q;
	queue<node> Q;
	p.x = x, p.y = y;
	p.step = 0;
	Q.push(p);
	book[x][y] = true;
	while(!Q.empty()){
		p = Q.front();
		Q.pop();
		if(map[p.x][p.y] >= 'A' && map[p.x][p.y] <= 'Z')
			e[s][b[p.x][p.y]] = p.step;
		for(int i = 0; i < 4; ++i){
			q.x = p.x + dir[i][0];
			q.y = p.y + dir[i][1];
			if(q.x < m && q.x >= 0 && q.y >= 0 && q.y < n && book[q.x][q.y] == false && map[q.x][q.y] != '#'){
				book[q.x][q.y] = true;
				q.step = p.step + 1;
				Q.push(q);
			}
		}
	}
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		fill(e[0], e[0] + N*N, INF);
		fill(dis, dis + N, INF);
		memset(visit, false, sizeof(visit));
		scanf("%d%d", &n, &m);
		int cnt = 1;
		gets(map[0]);
		for(int i = 0; i < m; ++i){
			gets(map[i]);
			for(int j = 0; j < n; ++j)
				if(map[i][j] <= 'Z' && map[i][j] >= 'A')
					b[i][j] = cnt++;
		}
		for(int i = 0; i < m; ++i)
			for(int j = 0; j < n; ++j)
				if(map[i][j] >= 'A' && map[i][j] <= 'Z')
					bfs(b[i][j], i, j);
		int sum = 0;
		n = cnt - 1;
		dis[1] = 0;
		for(int i = 0; i < n; ++i){
			int u = -1, minn = INF;
			for(int j = 1; j <= n; ++j)
				if(visit[j] == false && dis[j] < minn){
					minn = dis[j];
					u = j;
				}
			if(u == -1)	break;
			visit[u] = true;
			sum += minn;
			for(int v = 1; v <= n; ++v)
				if(visit[v] == false && dis[v] > e[u][v])
					dis[v] = e[u][v];
		}
		printf("%d\n", sum);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37691414/article/details/82114810
今日推荐