题目:
http://poj.org/problem?id=2312
大意:
给你一个m行n列的矩阵。
Y代表起点,T代表终点。B、E可以走,S、R不可以走,B的时间花费为2,E为1.
求Y到T的最短时间。
思路:
简单的广搜
代码如下:
#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> #include<cmath> using namespace std; int MaxRow, MaxCol; char map[305][305]; bool visit[305][305]; int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; //上,下,右,左 typedef struct tank { int x, y, cost; }; bool operator < (const tank &a, const tank &b) //优先队列,队头为最优解。即花费最少 { return a.cost > b.cost; } bool is_error(int x, int y) //是否为边界或障碍 { if(x < 0 || y < 0 || x >= MaxRow || y >= MaxCol) return 1; if(map[x][y] == 'R' || map[x][y] == 'S' || visit[x][y]) return 1; return 0; } bool BFS(int a, int b) //广搜,找到即为最优解 { int x, y; priority_queue<tank> que; //优先队列 tank in, out; in.x = a; in.y = b; in.cost = 0; que.push(in); //起点 while(!que.empty()) { out = que.top(); //出队寻找四个方向,满足条件则入队 que.pop(); if(map[out.x][out.y] == 'T') //结束 { printf("%d\n", out.cost); return true; } for(int i = 0; i < 4; ++i) //四个方向 { x = out.x + dir[i][0]; //x,y用于记录out.x的四个方向,不能用out.x += dir[i][0]。则每次out.x值都改变!~ y = out.y + dir[i][1]; if(is_error(x, y)) //是否为边界或障碍 continue; visit[x][y] = 1; //搜过则标记 in.x = x; in.y = y; in.cost = out.cost + 1; if(map[x][y] == 'B') in.cost++; que.push(in); //满足条件入队 } } return false; } int main() { int StartRow, StartCol; while(scanf("%d%d", &MaxRow, &MaxCol) && MaxRow && MaxCol) { memset(visit, 0, sizeof(visit)); getchar(); //吃掉scanf留下的\n for(int i = 0; i < MaxRow; ++i) gets(map[i]); for(int i = 0; i < MaxRow; ++i) for(int j = 0; j < MaxCol; ++j) if(map[i][j] == 'Y') //起点 { StartRow = i; StartCol = j; } visit[StartRow][StartCol] = 1; //起点标记 if(!BFS(StartRow, StartCol)) printf("-1\n"); } return 0; }