POJ_2049_Finding Nemo(BFS+优先队列)
/*
看了网络大神的代码,觉得要学习的东西真的很多,下面把我看完代码之后的理解分享一下。
这道题用到的算法就是广度优先遍历(BFS)和优先队列。别人不说是广搜,真的看不出来。
1:题意就是一个人从外面往方格里面走只能经过门,不能经过墙。
问你到达目的点最少经过的门数。可以反向思维我们可以从里面往外走,找最少的门数。
2:优先队列的用法,见代码,在这里优先队列的作用就是,每次出队的时候不是先入得先出
而是找门数最少的先出队。
3:广度搜索。while循环那里就是使用了广搜,因为广搜的实现就是用的队列。
4:上下左右方向移动的实现,用的师叔祖实现,而不是if控制。
*/
1 # include <stdio.h> 2 # include <string.h> 3 # include <queue> 4 using namespace std; 5 int map[250][250][2],position[250][250]; 6 //我用小方形的左下的坐标表示这个小方形(譬如,Nemo的坐标为(1.5,1.5) 7 //则他所在的小方形为(1,1)posi[i][j]指的是小方形的坐标, 8 //map[0][i][j]为坐标为(i,j),平行于x轴的一个墙(或门,空气),map[1][i][j]则为平行于y轴的... 9 typedef struct node 10 { 11 int x; 12 friend bool operator < (struct node a,struct node b) 13 { 14 return a.door>b.door; 15 } 16 int y,door; 17 }LINK; 18 int main() 19 { 20 int i,j,n,m,x,y,d,t; 21 int tx,ty,td,flag,door,txx,tyy; 22 int maxx,maxy,minx,miny; 23 int dd[4]={0,1,1,0},xx[4]={0,0,1,0},yy[4]={0,0,0,1}; 24 int xxx[4]={0,-1,1,0},yyy[4]={-1,0,0,1}; 25 // dd[]指到某个小正方形里面后可去的四个方向,我是按下、左、右、上的顺序, 26 // xx[],yy[],xxx[],yyy[]与之对应,xx[],yy[]指去这个方向时 27 // 要通过的边的坐标(map[][][]), 28 // xxx,yyy指通过边后到达的新的小方形的坐标(posi[][]), 29 double f1,f2; 30 LINK tem; 31 priority_queue<LINK> q; 32 while(scanf("%d%d",&m,&n)!=EOF) 33 { 34 if(m==-1 && n==-1) 35 break; 36 memset(map,0,sizeof(map)); 37 memset(position,0,sizeof(position)); 38 maxx=maxy=-20; 39 minx=miny=220; 40 while(m--) 41 { 42 scanf("%d%d%d%d",&x,&y,&d,&t); 43 for(i=0;i<t;i++) 44 map[x+i*(1-d)][y+i*d][d]=1;//1指墙 45 if(x<minx) 46 minx=x; 47 if(y<miny) 48 miny=y; 49 if(x>maxx) 50 maxx=x; 51 if(y>maxy) 52 maxy=y; 53 } 54 while(n--) 55 { 56 scanf("%d%d%d",&x,&y,&d); 57 map[x][y][d]=2;//2指门 58 } 59 scanf("%lf%lf",&f1,&f2); 60 x=(int) f1; 61 y=(int) f2; 62 if(x<minx || y<miny ||x>maxx || y>maxy) 63 { 64 printf("0\n"); 65 continue; 66 } 67 while(!q.empty()) 68 q.pop(); 69 tem.x=x; 70 tem.y=y; 71 tem.door=0; 72 q.push(tem); 73 flag=0; 74 position[x][y]=1; 75 while(!q.empty()) 76 { 77 tem=q.top(); 78 q.pop(); 79 x=tem.x; 80 y=tem.y; 81 door=tem.door; 82 if(x>=maxx || x<minx || y>=maxy || y<miny) 83 { 84 flag=1;break; 85 } 86 for(i=0;i<4;i++) 87 { 88 td=dd[i]; 89 tx=xx[i]+x; 90 ty=yy[i]+y; 91 txx=xxx[i]+x; 92 tyy=yyy[i]+y; 93 if(map[tx][ty][td]==2 && position[txx][tyy]==0) 94 { 95 tem.x=txx; 96 tem.y=tyy; 97 tem.door=door+1; 98 position[txx][tyy]=1; 99 q.push(tem); 100 } 101 if(map[tx][ty][td]==0 && position[txx][tyy]==0) 102 { 103 position[txx][tyy]=1; 104 tem.x=txx; 105 tem.y=tyy; 106 tem.door=door; 107 q.push(tem); 108 } 109 } 110 } 111 if(flag==1) 112 printf("%d\n",door); 113 else 114 printf("-1\n"); 115 } 116 return 0; 117 }