優先隊列+BFS(廣度優先搜索)

優先隊列

優先隊列容器與隊列一樣,只能從隊尾插入元素,從隊首刪除元素。但是它有一個特性,就是隊列中最大的元素總是位於隊首,所以出隊時,並非按照先進先出的原則進行,而是將當前隊列中最大的元素出隊。這點類似於給隊列裏的元素進行了由大到小的順序排序。元素的比較規則默認按元素值由大到小排序,可以重載“<”操作符來重新定義比較規則,和普通隊列不同的是,隊首元素是q.top()。

題目

在育英,大家最頭疼的事情就是晨跑了,因爲每天早上大家都要被迫從溫暖的被窩爬起來去晨跑令人非常不爽。
育英的晨跑是使用一款APP來規定晨跑路線,我們可以把育英校園看作一個n * m的二維矩陣。LZY的起點在左上角(0,0),而APP規定的終點爲右下角(n - 1,m - 1) 。
LZY跑到每個點的用時都不一樣,現在LZY爲了偷懶,想找一條耗時最短的捷徑,你能幫幫他嗎?

輸入格式

測試樣例由多組測試數據組成。每組測試數據第一行輸入兩個正整數n, m(1 <= n,m <= 100)
接下來輸入n*m個數字,每個數字不超過500

輸出

輸出LZY從起點跑到終點的最短用時

輸入樣例

3 3
3 2 1
3 2 1
3 2 1

輸出樣例

8

代碼

利用排序規則,讓時間更短的路徑出隊順序,提高效率。

#include<bits/stdc++.h>
using namespace std;
int n,m,k,mixn;
int vis[110][110];
int Map[110][110]; 
int dir[4][2]={-1,0,1,0,0,-1,0,1};
struct fun{
	int x,y;
	int t;
	friend bool operator<(fun a,fun b){
		return a.t>b.t;//相反的     時間短的在前面
	}
}great;
void bfs(){
	priority_queue<fun> q;
	great.x=0;
	great.y=0;
	great.t=Map[0][0];
	vis[0][0]=1;
	q.push(great);
	mixn=0x7fffffff;
	while(q.size()){
		fun num=q.top();
		q.pop();
		if(num.x==n-1&&num.y==m-1){
			mixn=num.t;
		}
		for(int i=0;i<4;i++){
			int xx=num.x+dir[i][0];
			int yy=num.y+dir[i][1];
			if(xx<0||xx>=n||yy<0||yy>=m||num.t+Map[xx][yy]>mixn){
				continue;
			}
			if(vis[xx][yy]==0){
				vis[xx][yy]=1;
				great.x=xx;
				great.y=yy;
				great.t=num.t+Map[xx][yy];
				q.push(great);
			}
		}
	}
}
int main(){
	while(scanf("%d %d",&n,&m)!=EOF){
		memset(vis,0,sizeof(vis));
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				scanf("%d",&Map[i][j]);
			}
		}
		bfs();
		printf("%d\n",mixn);
	}
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章