poj 2049.Finding Nemo

Finding Nemo

#include<iostream.h>

const int INF=100000000;
const int MAX_SIZE=256;

struct PriorityQueueNode{
	int x,y;
	int p;
};

int M, N;
int x,y,d,t;
double f1,f2;
int vEdge[MAX_SIZE][MAX_SIZE];
int hEdge[MAX_SIZE][MAX_SIZE];
int dist[MAX_SIZE][MAX_SIZE];

int xmax, ymax;
int xd, yd;
int PriorityQueueSize;
PriorityQueueNode priorityQueue[MAX_SIZE*MAX_SIZE];

//初始化优先队列为空队列,即置其长度为0. 
inline void InitPriorityQueue();
//返回优先队列队首元素的只读引用,不改变优先队列状态. 
inline const PriorityQueueNode& PeekPriorityQueue();
//判断优先队列是否为空,是返回tru额,否返回false. 
inline bool IsEmptyPriorityQueue();
//出队 
void DeletePriorityQueue();
//入队 
void EnterPriorityQueue(const PriorityQueueNode& pqn);
//广度优先遍历求解. 
int Bfs(); 

int main()
{
	int i, j; 
	
	while(cin>>M>>N&&!(M==-1&&N==-1)){
		//初始化各边的权值为0
		for(i=0;i<MAX_SIZE;i++){
			for(j=0;j<MAX_SIZE;j++){
				vEdge[i][j]=hEdge[i][j]=0;
			}
		}
		
		//读入每一个墙的信息
		for(i=0;i<M;i++){
			cin>>x>>y>>d>>t;
			if(d==0){
				for(j=0;j<t;j++){
					vEdge[x+j][y]=INF;
				}
				if(xmax<x+t){
					xmax=x+t;
				}
				if(ymax<y){
					ymax=y;
				}
			}
			else{
				for(j=0;j<t;j++){
					hEdge[x][y+j]=INF;
				}
				if(xmax<x){
					xmax=x;
				}
				if(ymax<y+t){
					ymax=y+t;
				}
			}
		} 
		
		//读入每一个门的信息 
		for(i=0;i<N;i++){
			cin>>x>>y>>d;
			if(d==0){
				hEdge[x][j]=1;
			}
			else{
				vEdge[x][y]=1;
			}
		}
	
		cin>>f1>>f2;
	
		//求解并输出结果.
		if(f1>xmax||f2>ymax){
			cout<<'0'<<endl;
		} 
		else{
			xd=(int)f1;
			yd=(int)f2;
			cout<<Bfs()<<endl;
		}
	}
	return 0;
} 

inline void InitPriorityQueue()
{
	PriorityQueueSize=0;
}

inline const PriorityQueueNode& PeekPriorityQueue()
{
	return priorityQueue[0];
}

inline bool IsEmptyPriorityQueue()
{
	if(PriorityQueueSize>0){
		return false;
	}
	return true;
}

void DeletePriorityQueue()
{
	PriorityQueueNode t=priorityQueue[PriorityQueueSize-1];
	PriorityQueueSize--;
	int par=0,chi=1;
	while(chi<PriorityQueueSize)
	{
		if(chi+1<PriorityQueueSize&&priorityQueue[chi+1].p<priorityQueue[chi].p){
			chi++;
		} 
		if(priorityQueue[chi].p<t.p){
			priorityQueue[par]=priorityQueue[chi];
			par=chi;
			chi=2*par+1;
		}
		else{
			break;
		}
	}
	priorityQueue[par]=t;
}

void EnterPriorityQueue(const PriorityQueueNode& pqn)
{
	PriorityQueueSize++;
	int chi=PriorityQueueSize-1, par=(chi-1)/2;//下标从0开始 
	while(chi>0&&pqn.p<priorityQueue[par].p){
		priorityQueue[chi]=priorityQueue[par];
		chi=par;
		par=(chi-1)/2;
	}
	priorityQueue[chi]=pqn;
}

int Bfs()
{
	PriorityQueueNode pqn;
	int i,j;
	
	for(i=0;i<=xmax;i++){
		for(j=0;j<=ymax;j++){
			dist[i][j]=INF;
		}
	}
	
	dist[0][0]=0;
	InitPriorityQueue();
	pqn.x=0;
	pqn.y=0;
	pqn.p=0;
	EnterPriorityQueue(pqn);
	while(!IsEmptyPriorityQueue()){
		pqn=PeekPriorityQueue();
		DeletePriorityQueue();
		int x=pqn.x, y=pqn.y;
		
		//广度优先遍历到目标顶点. 
		if(x==xd&&y==yd){
			return dist[x][y];
		}
		
		//检查网格(x,y)上方网格对应图G的顶点. 
		if(y+1<=ymax&&dist[x][y+1]>dist[x][y]+vEdge[x][y+1]){
			dist[x][y+1]=dist[x][y]+vEdge[x][y+1];
			pqn.x=x;
			pqn.y=y+1;
			pqn.p=dist[x][y+1];
			EnterPriorityQueue(pqn);
		}
		//检查网格(x,y)右方网格对应图G的顶点.
		 if(x+1<=xmax&&dist[x+1][y]>dist[x][y]+hEdge[x+1][y]){
			dist[x+1][y]=dist[x][y]+hEdge[x+1][y];
			pqn.x=x+1;
			pqn.y=y;
			pqn.p=dist[x+1][y];
			EnterPriorityQueue(pqn);
		}
		//检查网格(x,y)下方网格对应图G的顶点.
		if(y-1>=0&&dist[x][y-1]>dist[x][y]+vEdge[x][y]){
			dist[x][y-1]=dist[x][y]+vEdge[x][y-1];
			pqn.x=x;
			pqn.y=y-1;
			pqn.p=dist[x][y-1];
			EnterPriorityQueue(pqn);
		}
		//检查网格(x,y)左方网格对应图G的顶点.
		if(x-1>=0&&dist[x-1][y]>dist[x][y]+hEdge[x][y]){
			dist[x-1][y]=dist[x][y]+hEdge[x][y];
			pqn.x=x-1;
			pqn.y=y;
			pqn.p=dist[x-1][y];
			EnterPriorityQueue(pqn);
		} 
	}
	return -1;
} 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值