Haunted Graveyard

来源:互联网 发布:it strikes me that 编辑:程序博客网 时间:2024/05/01 18:36
                                                                    Haunted Graveyard
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 251 Accepted: 61

Description

Tonight is Halloween and Scared John and his friends  have decided to do something fun to celebrate the occasion: crossing the  graveyard. Although Scared John does not find this fun at all, he finally agreed  to join them in their adventure. Once at the entrance, the friends have begun to  cross the graveyard one by one, and now it is the time for Scared John. He still  remembers the tales his grandmother told him when he was a child. She told him  that, on Halloween night, "haunted holes" appear in the graveyard. These are not  usual holes, but they transport people who fall inside to some point in the  graveyard, possibly far away. But the scariest feature of these holes is that  they allow one to travel in time as well as in space; i.e., if you fall inside a  "haunted hole", you appear somewhere in the graveyard a certain time before (or  after) you entered the hole, in a parallel universe otherwise identical to ours.
The graveyard is organized as a grid of W*H cells, with the entrance in the  cell at position (0, 0) and the exit at (W-1, H-1). Despite the darkness, Scared  John can always recognize the exit, and he will leave as soon as he reaches it,  determined never to set foot anywhere in the graveyard again. On his way to the  exit, he can walk from one cell to an adjacent one, and he can only head to the  North, East, South or West. In each cell there can be either one gravestone, one  "haunted hole", or grass:


If the cell contains a gravestone, you cannot  walk over it, because gravestones are too high to climb.
If the cell  contains a "haunted hole" and you walk over it, you will appear somewhere in the  graveyard at a possibly different moment in time. The time difference depends on  the particular "haunted hole" you fell into, and can be positive, negative or  zero.
Otherwise, the cell has only grass, and you can walk freely over it.


He is terrified, so he wants to cross the graveyard as quickly as  possible. And that is the reason why he has phoned you, a renowned programmer.  He wants you to write a program that, given the description of the graveyard,  computes the minimum time needed to go from the entrance to the exit. Scared  John accepts using "haunted holes" if they permit him to cross the graveyard  quicker, but he is frightened to death of the possibility of getting lost and  being able to travel back in time indefinitely using the holes, so your program  must report these situations.



Figure 3 illustrates a  possible graveyard (the second test case from the sample input). In this case  there are two gravestones in cells (2, 1) and (3, 1), and a "haunted hole" from  cell (3, 0) to cell (2, 2) with a difference in time of 0 seconds. The minimum  time to cross the graveyard is 4 seconds, corresponding to the path:

If you do not use the "haunted  hole", you need at least 5 seconds.

Input

The input consists of several test cases. Each test  case begins with a line containing two integers W and H (1 <= W, H <= 30).  These integers represent the width W and height H of the graveyard. The next  line contains an integer G (G >= 0), the number of gravestones in the  graveyard, and is followed by G lines containing the positions of the  gravestones. Each position is given by two integers X and Y (0 <= X < W  and 0 <= Y < H).
The next line contains an integer E (E >= 0), the  number of "haunted holes", and is followed by E lines. Each of these contains  five integers X1, Y1, X2, Y2, T. (X1, Y1) is the position of the "haunted hole"  (0 <= X1 < W and 0 <= Y1 < H). (X2, Y2) is the destination of the  "haunted hole" (0 <= X2 < W and 0 <= Y2 < H). Note that the origin  and the destination of a "haunted hole" can be identical. T (10 000 <= T < = 10 000) is the difference in seconds between the moment somebody enters  the "haunted hole" and the moment he appears in the destination position; a  positive number indicates that he reaches the destination after entering the  hole. You can safely assume that there are no two "haunted holes" with the same  origin, and the destination cell of a "haunted hole" does not contain a  gravestone. Furthermore, there are neither gravestones nor "haunted holes" at  positions (0,0) and (W-1,H-1). The input will finish with a line containing 0 0,  which should not be processed.

Output

For each test case, if it is possible for Scared John  to travel back in time indefinitely, output Never. Otherwise, print the minimum  time in seconds that it takes him to cross the graveyard from the entrance to  the exit if it is reachable, and Impossible if not.

Sample Input

3 322 11 204 322 13 113 0 2 2 04 2012 0 1 0 -30 0

Sample Output

Impossible4Never
http://poj.org/problem?id=3878
很经典的搜索图求两点最短路径的题目,如果图中存在负权环,就输出never,不可达就输出impossible,图中可以存在单边环,这种情况如果是负权的话就输出never,如果是正权的话,就忽略这一小格。
接下来就是建图了,参考了构轩师兄的做法,用一个类来集合图的邻接表,添加边的函数,spfa搜索算法的函数等等操作,spfa算法中使用了记录结点是否在队列中的数组,以及记录结点松弛次数的数组来优化算法和检测是否有负权环的存在,一发现负权环即退出搜索。
由于这道题存在的边较多,测试数据可能也比较多组,刚提交时超时了,后来删除和优化了不必要的初始化变量和赋值等操作,并把输出格式从c++风格改为了c风格的,就800多ms刚好能通过了。
 
#include <cstdio>#include <cstdlib>#include <vector>#include <queue>#include <algorithm>using namespace std;const int INF=0x3fffffff;class Sssp{       //single source shortest path graphicstruct edge{int to,weight;edge(int t,int w):to(t),weight(w){}};vector<vector<edge>> adj;vector<int> dist;public:void init(int nodes){adj.clear();adj.resize(nodes);dist.resize(nodes);fill(dist.begin(),dist.end(),INF);}void addedge(int node,int dest,int wei){edge ed(dest,wei);adj[node].push_back(ed);}int spfa();};int Sssp::spfa(){queue<int> q;vector<int> cnt(adj.size(),0);vector<bool> inq(adj.size(),false);q.push(0);inq[0]=true;dist[0]=0;while(!q.empty()){int node=q.front();q.pop();inq[node]=false;for(int i=0;i<adj[node].size();++i){int dest=adj[node][i].to;int wei=adj[node][i].weight;if(dist[dest]>dist[node]+wei){if(dest==0)return -INF;dist[dest]=dist[node]+wei;++cnt[dest];if(cnt[dest]>=adj.size())return -INF;if(!inq[dest]){q.push(dest);inq[dest]=true;}}}}return dist[adj.size()-1];}enum status{entry,grass,stone,hole,out};status graphic[30][30];int w,h;Sssp sssp;inline int getnode(int x,int y){return  x*h+y;}void solve(){    scanf("%d %d",&w,&h);if(w==0&&h==0)exit(0);sssp.init(w*h);fill(graphic[0],graphic[30],grass);graphic[0][0]=entry;graphic[w-1][h-1]=out;int gsto;scanf("%d",&gsto);while(--gsto>=0){int x,y;scanf("%d %d",&x,&y);graphic[x][y]=stone;}int hunthole;scanf("%d",&hunthole);while(--hunthole>=0){int x1,y1,x2,y2,t;scanf("%d %d %d %d %d",&x1,&y1,&x2,&y2,&t);graphic[x1][y1]=hole;sssp.addedge(getnode(x1,y1),getnode(x2,y2),t);}static int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};for(int i=0;i<w;++i)for (int j=0;j<h;++j){if(graphic[i][j]==grass||graphic[i][j]==entry){int node=getnode(i,j);for (int k=0;k<4;++k){int x=i+dir[k][0];int y=j+dir[k][1];if(x>=w||x<0||y>=h||y<0)continue;if (graphic[x][y]!=stone){sssp.addedge(node,getnode(x,y),1);}}}}int dest=sssp.spfa();if(dest==-INF)printf("Never\n");else if(dest==INF)printf("Impossible\n");elseprintf("%d\n",dest);}int main(){while(true)solve();return 0;}

原创粉丝点击