优先队列
优先队列容器与队列一样,只能从队尾插入元素,从队首删除元素。但是它有一个特性,就是队列中最大的元素总是位于队首,所以出队时,并非按照先进先出的原则进行,而是将当前队列中最大的元素出队。这点类似于给队列里的元素进行了由大到小的顺序排序。元素的比较规则默认按元素值由大到小排序,可以重载“<”操作符来重新定义比较规则,和普通队列不同的是,队首元素是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从起点跑到终点的最短用时
输入样例
1 | 3 3 |
2 | 3 2 1 |
3 | 3 2 1 |
4 | 3 2 1 |
输出样例
8
代码
利用排序规则,让时间更短的路径出队顺序,提高效率。
1 |
|
2 | using namespace std; |
3 | int n,m,k,mixn; |
4 | int vis[110][110]; |
5 | int Map[110][110]; |
6 | int dir[4][2]={-1,0,1,0,0,-1,0,1}; |
7 | struct fun{ |
8 | int x,y; |
9 | int t; |
10 | friend bool operator<(fun a,fun b){ |
11 | return a.t>b.t;//相反的 时间短的在前面 |
12 | } |
13 | }great; |
14 | void bfs(){ |
15 | priority_queue<fun> q; |
16 | great.x=0; |
17 | great.y=0; |
18 | great.t=Map[0][0]; |
19 | vis[0][0]=1; |
20 | q.push(great); |
21 | mixn=0x7fffffff; |
22 | while(q.size()){ |
23 | fun num=q.top(); |
24 | q.pop(); |
25 | if(num.x==n-1&&num.y==m-1){ |
26 | mixn=num.t; |
27 | } |
28 | for(int i=0;i<4;i++){ |
29 | int xx=num.x+dir[i][0]; |
30 | int yy=num.y+dir[i][1]; |
31 | if(xx<0||xx>=n||yy<0||yy>=m||num.t+Map[xx][yy]>mixn){ |
32 | continue; |
33 | } |
34 | if(vis[xx][yy]==0){ |
35 | vis[xx][yy]=1; |
36 | great.x=xx; |
37 | great.y=yy; |
38 | great.t=num.t+Map[xx][yy]; |
39 | q.push(great); |
40 | } |
41 | } |
42 | } |
43 | } |
44 | int main(){ |
45 | while(scanf("%d %d",&n,&m)!=EOF){ |
46 | memset(vis,0,sizeof(vis)); |
47 | for(int i=0;i<n;i++){ |
48 | for(int j=0;j<m;j++){ |
49 | scanf("%d",&Map[i][j]); |
50 | } |
51 | } |
52 | bfs(); |
53 | printf("%d\n",mixn); |
54 | } |
55 | return 0; |
56 | } |