HDU - 4076(spfa)

题意:有n*m个点,每一点可以向四个方向走,有些点是墓地不能走,有些点是山洞,当你走到该点时会传送到另外一点,所花费的时间有可能是个正数也可能是个负数

也可能是0。起点是(0,0),目的地是(n-1,m-1),题目保证起点和终点不会是墓地也不会是山洞。如果有可能永远都到达不了终点也就是该图存在负权回路,输出Never;

否则输出需最少的花费时间或者Impossible;

题解: 用优先队列走上下左右然后更新,然后用spfa判断环原理判断是否有个点入队n×m次如果有就是存在负环,最后的n×m的答案就是距离,在注意一些走到终点或者掉进洞就直接进洞不用上下左右更新

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define mes(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(i = a; i <= b; i++)
#define dec(i,a,b) for(i = b; i >= a; i--)
#define fi first
#define se second
#define ls rt<<1
#define rs rt<<1|1
#define mid (L+R)/2
#define lson ls,L,mid
#define rson rs,mid+1,R
#define inf 0x3f3f3f3f
typedef double db;
typedef long long int ll;
typedef pair pii;
typedef unsigned long long ull;
const int mx = 1e5+5;
const int x_move[] = {1,-1,0,0,1,1,-1,-1};
const int y_move[] = {0,0,1,-1,1,-1,1,-1};
int n,m;
int w,h;
struct node{
	int x,y;
	int t;
	bool operator<(const node &a)const{
		return t>a.t;
	}
};
int dis[105][105];
int in[105][105];
int plat[105][105];
node edge[105][105];
bool check(int x,int y){
	return x >= 0&&x < w&&y >= 0&&y < h&&plat[x][y]==0;
}
void bfs(int x,int y){
	priority_queue q;
	node ft,pt;
	ft.x = x;
	ft.y = y;
	ft.t = 0;
	q.push(ft);
	dis[x][y] = 0;
	in[x][y]++;
	while(!q.empty()){
		node ft = q.top();
		q.pop();
		if(ft.x==w-1&&ft.y==h-1)
			continue;
		if(edge[ft.x][ft.y].x!=-1){
			int x = edge[ft.x][ft.y].x;
			int y = edge[ft.x][ft.y].y;
			int t = edge[ft.x][ft.y].t;
			if(ft.t+t=w*h){
					puts("Never");
					return;
				}
			}
			continue;
		}
		for(int i = 0; i < 4; i++){
			pt.x = ft.x+x_move[i];
			pt.y = ft.y+y_move[i];
			int x = pt.x;
			int y = pt.y;
			if(check(pt.x,pt.y)){
				if(dis[x][y]>ft.t+1){
					pt.t = dis[x][y] = ft.t+1;
					q.push(pt);
					in[x][y]++;
					if(in[x][y]>=w*h){
						puts("Never");
						return;
					}
				}
			}
		}
	}
	if(dis[w-1][h-1]==inf)
		puts("Impossible");
	else
		printf("%d\n",dis[w-1][h-1]);
}
int main(){
	int t,ca = 1;
	while(scanf("%d%d",&w,&h)!=EOF){
		if(w==0||h==0)
			break;
		memset(plat,0,sizeof(plat));
		memset(dis,inf,sizeof(dis));
		memset(in,0,sizeof(in));
		memset(edge,-1,sizeof(edge));
		scanf("%d",&n);
		for(int i = 1; i <= n; i++){
			int x,y; 
			scanf("%d%d",&x,&y);
			plat[x][y] = 1;
		}
		scanf("%d",&n);
		for(int i = 1; i <= n; i++){
			int x,y;
			//cout<<1<




你可能感兴趣的:(图论,BFS)