UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题

很少用bfs进行最短路搜索,实际BFS有时候挺方便得,省去了建图以及复杂度也降低了O(N*M);

UVA 11624 写的比较挫


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
struct node{
int ft;
int sta;
}flo[1010][1010];
int vis[1010][1010];
struct person{
int x,y,t,fx,fy;
};
int R,C;
int dir[][2]={{0,1},{0,-1},{1,0},{-1,0}};
typedef pair<int,int> pill;
queue<pill> v;
queue<person> q;
void init()
{
memset(vis,0,sizeof vis);
while (!v.empty()){
pill x=v.front();
v.pop();
for (int i=0;i<4;i++){
int nx=x.first+dir[i][0];
int ny=x.second+dir[i][1];
int tmp=flo[x.first][x.second].ft+1;;
if (nx<0 || ny<0 || nx>=R || ny>=C) continue;
if (flo[nx][ny].ft>=0 && flo[nx][ny].ft<=tmp || flo[nx][ny].sta==0) continue;
flo[nx][ny].ft=flo[x.first][x.second].ft+1;
pill b=make_pair(nx,ny);
if (!vis[nx][ny])
v.push(b);
vis[nx][ny]=1;
}
}
}
int bfs(person x)
{
memset(vis,0,sizeof vis);
while (!q.empty()) q.pop();
q.push(x);
int s=1<<30;
while (!q.empty()){
person u=q.front();
q.pop();
if (u.t>=s) continue;
if (u.x==0 || u.y==0 || u.x==R-1 || u.y==C-1) {s=u.t;break;}
for (int i=0;i<4;i++){
int xx=u.x+dir[i][0];
int yy=u.y+dir[i][1];
if (xx<0 || yy<0 || xx>=R || yy>=C) continue;
if (xx==u.fx && yy==u.fy) continue;
if (flo[xx][yy].sta!=1 || flo[xx][yy].ft>=0 && flo[xx][yy].ft<=u.t+1) continue;
person b=(person){xx,yy,u.t+1,u.x,u.y};
if (!vis[xx][yy]) q.push(b);
vis[xx][yy]=1;
}
}
return s;
}
int main()
{
int t,sx,sy;char ch;
scanf("%d",&t);
while (t--){
while (!v.empty()) v.pop();
scanf("%d%d",&R,&C);
getchar();
for (int i=0;i<R;i++){
for (int j=0;j<C;j++){
scanf("%c",&ch);
//cout<<ch<<endl;
if (ch==‘.‘) {flo[i][j].sta=1;flo[i][j].ft=-1;}
else if (ch==‘#‘){flo[i][j].sta=0;flo[i][j].ft=-1;}
else if (ch==‘F‘){
flo[i][j].sta=flo[i][j].ft=0;
pill a;a.first=i;a.second=j;v.push(a);
}
else if (ch==‘J‘) sx=i,sy=j;
}
getchar();
}
init();
person a=(person){sx,sy,0,-1,-1};
int ans=bfs(a);
if (ans<(1<<30)) printf("%d\n",ans+1);
else puts("IMPOSSIBLE");
}
return 0;
}

UVA 10047


#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
int R,C;
int vis[30][30][5][5];
int mat[30][30];
int sx,sy,ex,ey;
int dir[][2]={{-1,0},{0,1},{1,0},{0,-1}};
struct t1{
int x,y,d,c,t;
};
int bfs(t1 a)
{
queue<t1> q;
q.push(a);
memset(vis,0,sizeof vis);
while (!q.empty()){
t1 u=q.front();
q.pop();
if (u.x==ex && u.y==ey && u.c==0){
//cout<<" pass "<<u.x<<" "<<u.y<<endl;
return u.t;
}
vis[u.x][u.y][u.d][u.c]=1;
int nd=u.d+1;
if (nd>3) nd=0;
t1 nx=u;
nx.d=nd;
nx.t=u.t+1;
if (!vis[nx.x][nx.y][nx.d][nx.c]) q.push(nx);
vis[nx.x][nx.y][nx.d][nx.c]=1;
nd=u.d-1;
if (nd<0) nd=3;
nx=u; nx.d=nd; nx.t=u.t+1;
if (!vis[nx.x][nx.y][nx.d][nx.c]) q.push(nx);
vis[nx.x][nx.y][nx.d][nx.c]=1;
int xx=u.x+dir[u.d][0];
int yy=u.y+dir[u.d][1];
if (xx<0 || yy<0 || xx>=R || yy>=C) continue;
if (mat[xx][yy]==0) continue;
int nc=u.c+1;
if (nc>4) nc=0;
t1 b=(t1){xx,yy,u.d,nc,u.t+1};
if (!vis[b.x][b.y][b.d][b.c]) q.push(b);
vis[b.x][b.y][b.d][b.c]=1;
}
return -1;
}
int main()
{
char ch;
int kase=0;
while (scanf("%d%d",&R,&C)){
if (R==0) break;
getchar();
memset(mat,0,sizeof mat);
for (int i=0;i<R;i++){
for (int j=0;j<C;j++){
ch=getchar();
if (ch!=‘#‘) mat[i][j]=1;
if (ch==‘S‘) sx=i,sy=j;
if (ch==‘T‘) ex=i,ey=j;
}
getchar();
}
//cout<<ex<<" exy "<<ey<<endl;
t1 a=(t1){sx,sy,0,0,0};
int ans=bfs(a);
if (kase) puts("");
printf("Case #%d\n",++kase);
if (ans==-1)puts("destination not reachable");
else printf("minimum time = %d sec\n",ans);
}
return 0;
}

时间: 2024-10-22 05:36:51

UVA 11624 UVA 10047 两道用 BFS进行最短路搜索的题的相关文章

uva 11624 Fire!(多源BFS)

uva 11624 Fire! 题目大意:J在迷宫里工作,有一天迷宫起火了,火源有多处.每过一秒,火源都会向四个方向蔓延,J也会向四个方向移动,问J能不能跑出去,能的话输出他跑出去的最短时间,否则输出"IMPOSSIBLE" 解题思路:先进行一次BFS,找出每一点火焰蔓延到该处的最短时间.然后根据这张"火势图",对J的行进路线进行BFS.注意J在边缘的时候,以及没有火源的时候. #include <cstdio> #include <cstring

BFS(两点搜索) UVA 11624 Fire!

题目传送门 1 /* 2 BFS:首先对火搜索,求出火蔓延到某点的时间,再对J搜索,如果走到的地方火已经烧到了就不入队,直到走出边界. 3 */ 4 /************************************************ 5 Author :Running_Time 6 Created Time :2015-8-4 8:11:54 7 File Name :UVA_11624.cpp 8 ****************************************

逆向+两次bfs(UVA 1599)

为什么都说简单好想咧.坦白从宽看了人家的代码,涨了好多姿势,, http://blog.csdn.net/u013382399/article/details/38227917 被一个细节坑了.. 2147483647是0x7fffffff啊啊啊,7个f!!! 1 #include <iostream> 2 #include <sstream> 3 #include <cstdio> 4 #include <cstring> 5 #include <c

UVA 11624 - Fire!(BFS)

UVA 11624 - Fire! 题目链接 题意:一个迷宫,一些格子着火了,火每秒向周围蔓延,现在J在一个位置,问他能走出迷宫的最小距离 思路:BFS2次,第一次预处理每个位置着火时间,第二次根据这个再BFS一次 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int d[4][2] = {0, 1, 1, 0, 0, -1, -1, 0}; co

UVa 1599 Ideal Path (两次BFS)

题意:给出n个点,m条边的无向图,每条边有一种颜色,求从结点1到结点n颜色字典序最小的最短路径. 析:首先这是一个最短路径问题,应该是BFS,因为要保证是路径最短,还要考虑字典序,感觉挺麻烦的,并不好做,事实用两次BFS, 第一次是倒序BFS,目的是得到从结点 i 到结点n的最短距离,然后再从第一个点开始到最后一个,要保证在查找时,每经过一点要让d值恰好减少1, 直到终点,这也是一个BFS,因为这个字典序在某个结点是一样的,所以是两个BFS,我超时了好几次,因为少写了一个vis, 一定要细心,

BFS Fire! UVA - 11624

在一个矩形方阵里面,一个人要从一个位置走向另一个位置,其中某些地方有火源,每过一分钟,火源就会点燃相邻的点,同时相邻的点也变成了火源.人不能通过有火的点.问一个人能够安全地走到边界去最短时间多少?Unfortunately, portions of the maze havecaught on fire.portions of 是一些的意思. 两次bfs,首先从着火的点开始BFS进行预处理,在BFS求最短路. #include<iostream> #include<cstdio>

UVa 11624 Fire!(着火了!)

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: "Times New Roman"; font-size: 10.5000pt } h3 { margin-top: 5.0000pt; margin-bottom: 5.0000pt; text-align: left; font-family: 宋体; font-weight: bold; font-size: 1

UVA 816 - Abbott&#39;s Revenge(BFS)

UVA 816 - Abbott's Revenge 题目链接 题意:一个迷宫,每个点限制了从哪一方向来的,只能往左右前走,然后问起点到终点的最短路径 思路:BFS,每个点拆成4个方向的点,对应能走的方向建图跑一下bfs即可 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace

UVA 816 -- Abbott&#39;s Revenge(BFS求最短路)

 UVA 816 -- Abbott's Revenge(BFS求最短路) 有一个 9 * 9 的交叉点的迷宫. 输入起点, 离开起点时的朝向和终点, 求最短路(多解时任意一个输出即可).进入一个交叉点的方向(用NEWS表示不同方向)不同时, 允许出去的方向也不相同. 例如:1 2 WLF NR ER * 表示如果 进去时朝W(左), 可以 左转(L)或直行(F), 如果 朝N只能右转(R) 如果朝E也只能右转.* 表示这个点的描述结束啦! 输入有: 起点的坐标, 朝向, 终点的坐标.然后是各个