POJ 3026.Borg Maze

来源:互联网 发布:源美网络 半价商城 编辑:程序博客网 时间:2024/06/14 10:50

题目: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 55using 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个小时来调...

原创粉丝点击