Problem Description
在一个N*M的地图上旅行。地图上有些地方可以走用. 表示,不能走用 # 表示。在可以走的地方上下左右移动一格需要一个单位时间。可以走的地方还有一些时空之门。时空之门可以减少旅行的时间。如果 A 到 B 有一道时空之门,那么从 A 到 B 经过时空之门只要 1 个单位时间。在一个点可以有很多门通向其他的不同点。现在 john 在 s 点,他想以最快的时间到 t 点。求出最短时间。
Input
输入包含多组数据输入数据第一行两个正整数 N M (1< n,m <= 500) 接着 N 行,每行 M 个字符 表示地图。#表示不可走,.表示可以走,s表示开始位置,t表示终止位置。一个地图中只有一个s与1个t. 接着 N*M 行,给出每个点的时空之门。按行优先给出,即给出的顺序为(1,1),(1,2) ….. (1,m) ,(2,1)....(2,m)....。 每行第一个数 K 表示该点的时空之门数,接着给出 K 个点,表示该点通向这k个点的时间为1。其中时空之门的个数不超过100000。对于50%的数据,时空之门的个数为0 在给出的数据中,不能走的点#的时空之门数一定为0,且没有通向不能走的点的时空之门。
Output
s 到 t 的最短时间。数据保证s可以走到t。
Sample Input
2 2
s#
t.
0
0
0
0
Sample Output
1
讲解:其实现在看来还算是一个常规的题目,但是当时想着时空门,这个还关于跳跃越过去的问题,于是乎不知道该怎么写了,后来参考了一下学长的意见,似乎有点明白了,自己又写了一遍,供大家参考一下:
代码如下:
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdio> 4 #include<string> 5 #include<vector> 6 #include<queue> 7 #include<cstring> 8 using namespace std; 9 #define N 505 10 #define M 505 11 int n,m,step,si,sj,ti,tj,dir[][2]={{1,0},{-1,0},{0,1},{0,-1}}; 12 char map[N][M]; 13 bool flag[N][M]; 14 struct point{ 15 int x,y; 16 point (int x,int y):x(x),y(y){} 17 }; 18 vector<point>v[N][M];//把vector容器变为数组型的容器,方便数据的存储, 19 struct node 20 { 21 int x,y,t; 22 node(int x,int y,int t):x(x),y(y),t(t){} 23 node(){} 24 }; 25 queue<node>q; 26 void bfs() 27 { 28 while(!q.empty()) 29 q.pop(); 30 q.push(node(si,sj,0)); 31 map[si][sj]='#'; 32 int x,y,t; 33 node n1; 34 while(!q.empty()) 35 { 36 n1=q.front();q.pop(); 37 for(int i=0;i<4;i++)//常规的四个方向的寻找 38 { 39 x=n1.x+dir[i][0]; 40 y=n1.y+dir[i][1]; 41 if(map[x][y]!='#') 42 { 43 t=n1.t+1; 44 map[x][y]='#'; 45 if(x==ti && y==tj) 46 { 47 step=t; 48 return ; 49 } 50 q.push(node (x,y,t)); 51 } 52 } 53 int len=v[n1.x][n1.y].size(); 54 for(int i=0;i<len;i++)//取出满足条件的点,进行穿梭,然后再进行存储; 55 { 56 x=v[n1.x][n1.y][i].x; 57 y=v[n1.x][n1.y][i].y; 58 if(map[x][y]!='#') 59 { 60 t=n1.t+1; 61 map[x][y]='#'; 62 if(x==ti && y==tj) 63 { 64 step=t; 65 return ; 66 } 67 q.push(node (x,y,t)); 68 } 69 } 70 } 71 } 72 int main() 73 { 74 int i,j; 75 while(cin>>n>>m) 76 { 77 memset(map,'#',sizeof(map)); 78 getchar(); 79 for( i = 1; i <= n; ++i ) 80 { 81 gets(map[i]+1); 82 for( j = 1; j <= m; ++j ) 83 { 84 v[i][j].clear(); 85 if( map[i][j] == 's' ) si = i, sj = j; 86 else if( map[i][j] == 't' ) ti = i, tj = j; 87 } 88 } 89 int k,xx,yy; 90 for( i = 1; i <= n; ++i ) 91 { 92 for( j = 1; j <= m; ++j ) 93 { 94 scanf("%d", &k); 95 while(k--) 96 { 97 scanf("%d%d", &xx, &yy); 98 v[i][j].push_back(point(xx,yy));//这个二维的容器很好用,我也是刚学会的 99 } 100 } 101 } 102 bfs(); 103 cout<<step<<endl; 104 } 105 return 0; 106 }