FZU Problem 2028 时空门问题

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 }

 

 
posted on 2013-11-15 19:34  细雨微光  阅读(547)  评论(0)    收藏  举报