【STL】優先隊列priority_queue詳解+OpenJudge-4980拯救行動

1、關於優先隊列

隊列(queue)這種東西廣大OIer應該都不陌生,或者說,隊列都不會你還學個卵啊(╯‵□′)╯︵┻━┻咳咳,通俗講,隊列是一種只容許從前端(隊頭)刪除元素、從後端(隊尾)插入元素的數據結構。而優先隊列(priority queue)是一種賦予每一個隊列中元素以一個優先級的隊列。在執行刪除操做時,優先隊列會刪除具備最高優先級的元素。如此奇妙的優先隊列有什麼用呢,舉個例子,給定一個長爲n的序列和m組詢問,對於每組詢問,咱們要找出刪去序列中最小的數,再向序列加入一個數。樸素的想法是對每一個詢問從頭至尾掃一遍,找出最小值,時間複雜度爲O(nm)。而優先隊列能夠將時間複雜度下降到O(mlgn)的級別。那它是怎麼作到的呢?其實,優先隊列(又稱堆)是一顆徹底二叉樹,其每一個子節點與父節點間都具備某種特性(即爲咱們規定的優先級)。二叉樹的性質決定了優先隊列維護操做O(lgn)的複雜度。html

2、STL之priority_queue

優先隊列好用歸好用,然而,它很差寫_(:з」∠)_可是,STL(Standard Template Library 標準模板庫)裏給出了優先隊列的模板~\(≧▽≦)/~前端

priority_queue定義在頭文件<queue>裏,和普通隊列同樣,priority_queue擁有以下操做:node

一、priority_queue<Type, Container, Functional>Q:建立一個新的優先隊列Q,其Type爲其數據類型,Container 爲保存數據的容器,Functional 爲元素比較方式;後端

  特別說明:Container必須是用數組實現的容器,默認爲vector;Functional默認爲operator <。因此若是咱們把Container和Functional都缺省,優先隊列就是一個隊頭元素最大的大根堆。數組

二、Q.top():返回隊頭元素;數據結構

三、Q.pop():刪除隊列頭部元素;ide

四、Q.push(x):在隊尾增長元素x;spa

五、Q.empty():判斷隊列是否爲空(若是隊列爲空則返回true,不然,返回false);code

六、Q.size():返回隊列中元素個數。htm

3、OpenJudge-4980拯救行動題解

描述

公主被惡人抓走,被關押在牢房的某個地方。牢房用N*M (N, M <= 200)的矩陣來表示。矩陣中的每項能夠表明道路(@)、牆壁(#)、和守衛(x)。 
英勇的騎士(r)決定孤身一人去拯救公主(a)。咱們假設拯救成功的表示是「騎士到達了公主所在的位置」。因爲在通往公主所在位置的道路中可能遇到守衛,騎士一旦遇到守衛,必須殺死守衛才能繼續前進。 
現假設騎士能夠向上、下、左、右四個方向移動,每移動一個位置須要1個單位時間,殺死一個守衛須要花費額外的1個單位時間。同時假設騎士足夠強壯,有能力殺死全部的守衛。

給定牢房矩陣,公主、騎士和守衛在矩陣中的位置,請你計算拯救行動成功須要花費最短期。

輸入

第一行爲一個整數S,表示輸入的數據的組數(多組輸入)
隨後有S組數據,每組數據按以下格式輸入 
一、兩個整數表明N和M, (N, M <= 200). 
二、隨後N行,每行有M個字符。"@"表明道路,"a"表明公主,"r"表明騎士,"x"表明守衛, "#"表明牆壁。

輸出

若是拯救行動成功,輸出一個整數,表示行動的最短期。
若是不可能成功,輸出"Impossible"

原題連接→_→OpenJudge-4980拯救行動

讀了題咱們發現,這就是一個寬搜嘛。咱們只要以時間定義優先級,把每一個點能拓展的狀態放入優先隊列處理就能夠了。

愉快的貼上代碼:

 1 #include<cstdio>
 2 #include<queue>
 3 #include<cstring>
 4 using namespace std;
 5 const int MAXL=210;
 6 int dir[]={-1,1,0,0},dir_[]={0,0,-1,1};
 7 int s;
 8 int n,m;
 9 int map[MAXL][MAXL];
10 bool vis[MAXL][MAXL];
11 int dx,dy;
12 struct node 
13 {
14     int x,y,time;
15     friend bool operator < (node A,node B){return A.time>B.time;}
16     //重載 < ,定義時間爲優先級,時間小的元素置於隊首
17 };
18 priority_queue <node> q;//priority_queue <node,vector<node>,operator <> q; 
19 int main()
20 {
21     scanf("%d",&s);
22     while(s--)
23     {
24         while(!q.empty())q.pop();//清空隊列q,注意:沒有q.clear()的用法 
25         memset(vis,false,sizeof(vis));
26         memset(map,0,sizeof(map));
27         scanf("%d%d",&n,&m);
28         for(int i=1;i<=n;++i)
29         {
30             char c[MAXL];
31             scanf("%s",c);
32             for(int j=0;j<m;++j)
33             {
34                 if(c[j]=='a')dx=i,dy=j+1;
35                 else if(c[j]=='r')q.push((node){i,j+1,0}),vis[i][j+1]=true;
36                 else if(c[j]=='x')map[i][j+1]=1;//1表明守衛 
37                 else if(c[j]=='#')map[i][j+1]=2;//2表明牆壁 
38             }
39         }
40         while(!q.empty())
41         {
42             int x=q.top().x,y=q.top().y,time=q.top().time;
43             if(x==dx&&y==dy)break;
44             for(int i=0;i<4;++i)
45             {
46                 if(x+dir[i]<1||x+dir[i]>n||y+dir_[i]<1||y+dir_[i]>m)continue;
47                 if(vis[x+dir[i]][y+dir_[i]]||map[x+dir[i]][y+dir_[i]]==2)continue;
48                 vis[x+dir[i]][y+dir_[i]]=true;
49                 if(map[x+dir[i]][y+dir_[i]]==0)q.push((node){x+dir[i],y+dir_[i],time+1});
50                 else if(map[x+dir[i]][y+dir_[i]]==1)q.push((node){x+dir[i],y+dir_[i],time+2});
51             }
52             q.pop();
53         }
54         if(q.empty())printf("Impossible");
55         else printf("%d",q.top().time);
56         printf("\n");
57     }
58     return 0;
59 }
OpenJudge-4980拯救行動

弱弱地說一句,本蒟蒻碼字也不容易,轉載請註明出處http://www.cnblogs.com/Maki-Nishikino/p/6056072.html

相關文章
相關標籤/搜索