POJ 3026.Borg Maze

本文介绍了一种利用BFS和Prim算法解决迷宫中寻找所有A或S点间最短路径的方法。首先通过BFS计算两点间距离,并构建完全图;接着使用Prim算法计算最小生成树,得到所需的最短路径总和。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:http://poj.org/problem?id=3026

AC代码(C++):

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
#include <string>
#include <string.h>
#include <bitset>

#define INF 0xfffffff
#define MAXN 55

using namespace std;

struct POINT{
	int x,y;
	int step;
}from,to;

int n;
int x,y;
char g[MAXN][MAXN];

int map[MAXN*2][MAXN*2];
int dis[MAXN*2];
bool vis[MAXN*2];

int xy[MAXN][MAXN];

bool vist[MAXN][MAXN];

int dirx[4] = {0,1,0,-1};
int diry[4] = {1,0,-1,0};

void bfs(int sx, int sy) {
	queue<POINT> q;
	memset(vist, false, sizeof(vist));

	POINT ss;
	ss.x = sx;
	ss.y = sy;
	ss.step = 0;
	vist[sx][sy] = true;

	q.push(ss);

	while (!q.empty()) {
		from = q.front();
		q.pop();
		if(g[from.y][from.x]=='A'||g[from.y][from.x]=='S')map[xy[from.x][from.y]][xy[sx][sy]] = map[xy[sx][sy]][xy[from.x][from.y]] = from.step;
		for(int i = 0; i < 4; i++){
			to.x = from.x + dirx[i];
			to.y = from.y + diry[i];
			if (vist[to.x][to.y] == false && g[to.y][to.x] != '#') {
				vist[to.x][to.y] = true;
				to.step = from.step + 1;
				q.push(to);
			}
		}
	}
}

int Prim(){
    int ans = 0;
    for(int i=0;i<n;i++)dis[i]=map[0][i];
    memset(vis,false,sizeof(vis));
    vis[0]=1;
    for(int i=1;i<n;i++){
        int next,tmp = INF;
        for(int j=0;j<n;j++){
            if(!vis[j]&&tmp>dis[j]){
                tmp=dis[j];
                next=j;
            }
        }
        ans += tmp;
        vis[next]=1;
        for(int j=0;j<n;j++){
            if(!vis[j]&&dis[j]>map[next][j])
                dis[j]=map[next][j];
        }
    }
    return ans;
}

int main(){
	int t;
	scanf("%d",&t);
	for(int tt = 0; tt < t; tt++){
		n = 0;
		scanf("%d %d\n",&x,&y);
		for(int i = 0; i < y; i++){
			gets(g[i]);
			for(int j = 0; j < x; j++)if(g[i][j]=='A'||g[i][j]=='S'){
				xy[j][i] = n;
				n++;
			}
		}
		for(int i=0;i<y;i++){  
            for(int j=0;j<x;j++){  
                if(g[i][j] == 'S' || g[i][j] == 'A'){  
                    bfs(j,i);
                }  
            }  
        }
		printf("%d\n",Prim());
	}
}
总结: 这题技术上不难, 但是有点坑. 对于给定的迷宫, 首先找出所有的A或者S, 编号并保存位置. 然后求出两两间的距离, 构造完全图. 最后对这个完全图用Prim算法计算最小生成树, 所得权值既是所求. 看起来很简单的样子只需要BFS + Prim就能搞定, 但是一定要注意对BFS的优化. 一开始我用的BFS模板是在每次pop的时候操作vis数组, 然后就一直TLE, 直到我把这个vis操作放到push的后面...浪费我2个小时来调...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值