您的位置:首页 > 其它

hdu1072 Nightmare

2011-08-01 00:53 274 查看
BFS

此题与普通的BFS不同的是它的路径可以重复走,虽然空间代价不大(8*8),但
是如果你不能很好的判断没有出路的情况,那么就会陷入死循环。我是这么想的:我
先定义一个标记数组mark[][],出发点赋值为6。当你走到4时,那点的mark[][]值赋
为6。每次进队列时判断,如果当前点的mark值大于新生成点的mark时,才能进队列,
否则不能,这样就防止了进入死循环的情况。使用mark数组就省略了标记数组vis

不过,有一点,我始终不解,一到达终点就退出,这样保证了时间最短吗?可还是过了,困惑……

当然,也有遍历完所有点的

#include<iostream>
#include<queue>
using namespace std;
int map[9][9],mark[9][9],n,m,mins,si,sj;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
//mark[][]保存到达该点时所剩的时间
struct node
{
int x,y,time,cnt;//time 剩余时间;cnt 已花时间
};
node f;
void bfs()
{
f.x=si;f.y=sj;
f.cnt=0;f.time=6;
queue<node> q;
q.push(f);
mark[si][sj]=6;
while(!q.empty())
{
node t=q.front();
q.pop();
if(map[t.x][t.y]==3)
{
if(t.time>0)
{
mins=t.cnt;
return;
}
else continue;
}
if(map[t.x][t.y]==4)//重置时间
{
t.time=6;
mark[t.x][t.y]=6;
}
for(int k=0;k<4;k++)
{
node b;
b.x=t.x+dir[k][0];
b.y=t.y+dir[k][1];
b.cnt=t.cnt+1;
b.time=t.time-1;
if(b.x<=n&&b.x>0&&b.y<=m&&b.y>0&&map[b.x][b.y]!=0&&t.time>0&&mark[b.x][b.y]<b.time)//只有mark[b.x][b.y]<b.time时,才有必要入队
{
mark[b.x][b.y]=b.time;
q.push(b);
}
}
}
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cin>>map[i][j];
if(map[i][j]==2)
si=i,sj=j;
mark[i][j]=0;
}
}
mins=1000;
bfs();
if(mins!=1000)
cout<<mins<<endl;
else cout<<"-1"<<endl;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: