隊列(queue)這種東西廣大OIer應該都不陌生,或者說,隊列都不會你還學個卵啊(╯‵□′)╯︵┻━┻咳咳,通俗講,隊列是一種只容許從前端(隊頭)刪除元素、從後端(隊尾)插入元素的數據結構。而優先隊列(priority queue)是一種賦予每一個隊列中元素以一個優先級的隊列。在執行刪除操做時,優先隊列會刪除具備最高優先級的元素。如此奇妙的優先隊列有什麼用呢,舉個例子,給定一個長爲n的序列和m組詢問,對於每組詢問,咱們要找出刪去序列中最小的數,再向序列加入一個數。樸素的想法是對每一個詢問從頭至尾掃一遍,找出最小值,時間複雜度爲O(nm)。而優先隊列能夠將時間複雜度下降到O(mlgn)的級別。那它是怎麼作到的呢?其實,優先隊列(又稱堆)是一顆徹底二叉樹,其每一個子節點與父節點間都具備某種特性(即爲咱們規定的優先級)。二叉樹的性質決定了優先隊列維護操做O(lgn)的複雜度。html
優先隊列好用歸好用,然而,它很差寫_(:з」∠)_可是,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
公主被惡人抓走,被關押在牢房的某個地方。牢房用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 }
弱弱地說一句,本蒟蒻碼字也不容易,轉載請註明出處http://www.cnblogs.com/Maki-Nishikino/p/6056072.html