给定一个n*m的图,图上的每个点上的值为0或1,让你找到一条路,所经过的01序列最小。
思路:若开始为0,则广搜找到最远的0(离终点最近,即x+y最大)。然后开始用优先级队列搜索。
另外一种就是找到最远点后模拟搜索或者说斜推找到最小的(这种方法比较科学,因为和dir数组没有关系)。
ps:刚开始直接用广搜超时了,然后知道可能要找到最远的0,但是想复杂了。比赛时没做出来,有点遗憾。。。。dir数组必须先向下在向右,否则WA,不知为什么,难道数据弱?(本来想的是记录所有最大x+y,搜索每一个点,将所有结果比较,找到最小的,没想到……………………………………)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
点击打开链接斜推代码:
#include
#include
#include
#include
#include
using namespace std;
const int maxn = 1010;
struct node
{
int x, y;
};
char maps[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2] = {0, 1 , 1, 0 , -1,0, 0,-1};
int x, y, n, m;
bool Ok (int x, int y)
{
if (x<0 || y<0 || x>=n || y>=m)
return false;
return true;
}
void bfs ()
{
node p, q;
p.x = x, p.y = y;
queue Q;
Q.push (p);
while (!Q.empty())
{
p = Q.front();
Q.pop();
for (int i=0; i<4; i++)
{
q.x = p.x + dir[i][0];
q.y = p.y + dir[i][1];
if (Ok(q.x, q.y) && !vis[q.x][q.y])
{
vis[q.x][q.y] = true;
if (maps[q.x][q.y] == '0')
Q.push (q);
if (x + y < q.x + q.y)
x = q.x, y = q.y;
}
}
}
}
int main ()
{
int t;
scanf ("%d", &t);
while (t --)
{
memset (vis, false, sizeof(vis));
vis[0][0] = true;
scanf ("%d %d", &n, &m);
for (int i=0; i