View Code
/*hdu4076Haunted Graveyard
题意:一块h*w的墓地,每个格子可能是石头(障碍),洞(在t秒后到达某个位置,t可能为负),草地
(,0)为入口,(h-1,w-1)为出口。问从入口到出口的最短用时,若到不了输出Impossible,若用时无限小输出Never
无限小:存在负权回路
思路:存在负权,显然要用spfa。当对某一个点的松弛次数超过该图的顶点数h*w时就表示存在负权回路。
但是有一点需要注意:判断负权回路的时候不能把终点算在内,因为当第一次走到终点的时候就走出去了,终点不会对他的后继点进行松弛。
*/
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
#define MAXN 35
#define INF 100000000
typedef pair<int,int> pii;
int isStone[MAXN][MAXN],isHole[MAXN][MAXN],d[MAXN][MAXN],vis[MAXN][MAXN];//vis[]//[]记录松弛次数,d[][]表示耗时
int dir[4][2]={1,0,-1,0,0,1,0,-1};
int h,w,flag;//flag==1不存在最小路径(无限小)
struct HOLE
{
int x2,y2,t;
}hole[MAXN*MAXN];
bool out(int x,int y)
{
if(x<0||x>=h||y<0||y>=w)return true;
return false;
}
void BF()
{
queue <pii> q;
bool inq[MAXN][MAXN];
for(int i=0;i<h;i++)
for(int j=0;j<w;j++)
d[i][j]=INF;
d[0][0]=0;
memset(inq,0,sizeof(inq));
memset(vis,0,sizeof(vis));
inq[0][0]=1;
vis[0][0]=1;
q.push(make_pair(0,0));
while(!q.empty())
{
pii tmp;
tmp=q.front(),q.pop();
inq[tmp.first][tmp.second]=0;
if(tmp.first==h-1&&tmp.second==w-1)continue;
if(vis[tmp.first][tmp.second]>h*w){flag=1;return;}
if(isHole[tmp.first][tmp.second])//如果当前所在点是洞,不能停留
{
int index=isHole[tmp.first][tmp.second];
int xx=hole[index].x2,yy=hole[index].y2;
if(d[xx][yy]>d[tmp.first][tmp.second]+hole[index].t)
{
d[xx][yy]=d[tmp.first][tmp.second]+hole[index].t;vis[xx][yy]++;//松弛次数+1
if(!inq[xx][yy]){q.push(make_pair(xx,yy)),inq[xx][yy]=1;}
}
continue;
}
for(int i=0;i<4;i++)
{
int x=tmp.first+dir[i][0];
int y=tmp.second+dir[i][1];
if(out(x,y))continue;
if(isStone[x][y])continue;
if(d[x][y]>d[tmp.first][tmp.second]+1)
{
d[x][y]=d[tmp.first][tmp.second]+1;vis[x][y]++;//松弛次数+1
if(!inq[x][y]){q.push(make_pair(x,y)),inq[x][y]=1;}
}
}
}
}
int main()
{
int stoneNum,holeNum,x1,y1;
while(scanf("%d%d",&h,&w)==2)
{
if(!w&&!h)break;
scanf("%d",&stoneNum);
memset(isStone,0,sizeof(isStone));
memset(isHole,0,sizeof(isHole));
for(int i=0;i<stoneNum;i++)
{
scanf("%d%d",&x1,&y1);
isStone[x1][y1]=1;
}
scanf("%d",&holeNum);
for(int i=1;i<=holeNum;i++)
{
scanf("%d%d%d%d%d",&x1,&y1,&hole[i].x2,&hole[i].y2,&hole[i].t);
isHole[x1][y1]=i;
}
flag=0;
BF();
if(flag)printf("Never\n");
else if(d[h-1][w-1]==INF)printf("Impossible\n");
else printf("%d\n",d[h-1][w-1]);
}
}