優先隊列的使用:node
include<queue>//關聯頭文件 struct node{ int x,y; friend bool operator < (node d1,node d2) { return d1.x>d2.x; }//定義優先隊列運算規則必須 } //程序裏 priority_queue<node> q;//定義優先隊列 node cur,next; q.push(cur);//push !q.empty//隊列非空 cur=q.pop();//彈出 next=q.top();//隊首元素
加廣搜:ios
壓的時候一層層壓,隊列非空時一個個彈出,節點也帶上它的層數就行了git
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.算法
* Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
* Teleporting: FJ can move from any point X to the point 2 × X in a single minute.數組
If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?數據結構
貼代碼:性能
#include<iostream> #include<cstdio> #include<queue> using namespace std; int num,k; bool visit[200010]; priority_queue<node> q; struct node{ int d,n; friend bool operator < (node n1,node n2) { return n1.d > n2.d; } }; int bfs() { node cur,next; cur.n=num; cur.d=0; q.push(cur); visit[cur.n]=1; while (!q.empty()) { cur=q.top(); q.pop(); if (cur.n==k) { return cur.d; } next.n=cur.n+1; next.d=cur.d+1; if (next.n<200000 and next.n>0 and visit[next.n]==0) { q.push(next); visit[next.n]=1; } next.n=cur.n-1; if (next.n<200000 and next.n>0 and visit[next.n]==0) { q.push(next); visit[next.n]=1; } next.n=cur.n*2; if (next.n<200000 and next.n>0 and visit[next.n]==0) { q.push(next); visit[next.n]=1; } } return 0; } int main() { cin>>num>>k; for (int i=1;i<=k;i++) visit[i]=false; if (num>k) cout<<num-k; else cout<<bfs(); return 0; }
vector的使用://轉載自CSDN測試
vector 是C++ STL的一個重要成員,使用它時須要包含頭文件:優化
#include<vector>
1、vector 的初始化:能夠有五種方式,舉例說明以下:ui
(1) vector<int> a(10); //定義了10個整型元素的向量(尖括號中爲元素類型名,它能夠是任何合法的數據類型),但沒有給出初值,其值是不肯定的。
(2)vector
(3)vector
(4)vector
(5)int b[7]={1,2,3,4,5,9,8};
vector
2、vector對象的幾個重要操做,舉例說明以下:
(1)a.assign(b.begin(), b.begin()+3); //b爲向量,將b的0~2個元素構成的向量賦給a (2)a.assign(4,2); //是a只含4個元素,且每一個元素爲2 (3)a.back(); //返回a的最後一個元素 (4)a.front(); //返回a的第一個元素 (5)a[i]; //返回a的第i個元素,當且僅當a[i]存在2013-12-07 (6)a.clear(); //清空a中的元素 (7)a.empty(); //判斷a是否爲空,空則返回ture,不空則返回false (8)a.pop_back(); //刪除a向量的最後一個元素 (9)a.erase(a.begin()+1,a.begin()+3); //刪除a中第1個(從第0個算起)到第2個元素,也就是說刪除的元素從a.begin()+1算起(包括它)一直到a.begin()+ 3(不包括它) (10)a.push_back(5); //在a的最後一個向量後插入一個元素,其值爲5 (11)a.insert(a.begin()+1,5); //在a的第1個元素(從第0個算起)的位置插入數值5,如a爲1,2,3,4,插入元素後爲1,5,2,3,4 (12)a.insert(a.begin()+1,3,5); //在a的第1個元素(從第0個算起)的位置插入3個數,其值都爲5 (13)a.insert(a.begin()+1,b+3,b+6); //b爲數組,在a的第1個元素(從第0個算起)的位置插入b的第3個元素到第5個元素(不包括b+6),如b爲1,2,3,4,5,9,8 ,插入元素後爲1,4,5,9,2,3,4,5,9,8 (14)a.size(); //返回a中元素的個數; (15)a.capacity(); //返回a在內存中總共能夠容納的元素個數 (16)a.resize(10); //將a的現有元素個數調至10個,多則刪,少則補,其值隨機 (17)a.resize(10,2); //將a的現有元素個數調至10個,多則刪,少則補,其值爲2 (18)a.reserve(100); //將a的容量(capacity)擴充至100,也就是說如今測試a.capacity();的時候返回值是100.這種操做只有在須要給a添加大量數據的時候才 顯得有意義,由於這將避免內存屢次容量擴充操做(當a的容量不足時電腦會自動擴容,固然這必然下降性能) (19)a.swap(b); //b爲向量,將a中的元素和b中的元素進行總體性交換 (20)a==b; //b爲向量,向量的比較操做還有!=,>=,<=,>,<
3、順序訪問vector的幾種方式,舉例說明以下:
(1)向量a中添加元素
vector
for(int i=0;i<10;i++)
a.push_back(i);
二、也能夠從數組中選擇元素向向量中添加
int a[6]={1,2,3,4,5,6};
vector
for(int i=1;i<=4;i++)
b.push_back(a[i]);
三、也能夠從現有向量中選擇元素向向量中添加
int a[6]={1,2,3,4,5,6};
vector
vector
for(vector
b.push_back(*it);
四、也能夠從文件中讀取元素向向量中添加
ifstream in("data.txt");
vector
for(int i; in>>i)
a.push_back(i);
五、【誤區】
vector
for(int i=0;i<10;i++)
a[i]=i;
//這種作法以及相似的作法都是錯誤的。剛開始我也犯過這種錯誤,後來發現,下標只能用於獲取已存在的元素,而如今的a[i]仍是空的對象
(2)從向量中讀取元素
一、經過下標方式讀取
int a[6]={1,2,3,4,5,6};
vector
for(int i=0;i<=b.size()-1;i++)
cout<<b[i]<<" ";
二、經過遍歷器方式讀取
int a[6]={1,2,3,4,5,6};
vector
for(vector
cout<<*it<<" ";
4、幾種重要的算法,使用時須要包含頭文件:
#include<algorithm>
(1)sort(a.begin(),a.end()); //對a中的從a.begin()(包括它)到a.end()(不包括它)的元素進行從小到大排列
(2)reverse(a.begin(),a.end()); //對a中的從a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素爲1,3,2,4,倒置後爲4,2,3,1
(3)copy(a.begin(),a.end(),b.begin()+1); //把a中的從a.begin()(包括它)到a.end()(不包括它)的元素複製到b中,從b.begin()+1的位置(包括它)開始複製,覆蓋掉原有元素
(4)find(a.begin(),a.end(),10); //在a中的從a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
————————————————
版權聲明:本文爲CSDN博主「qinyuehong」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/qinyuehong/article/details/92837359
因而有了下面的題目:
一個山頭呼喊的聲音能夠被臨近的山頭同時聽到。題目假設每一個山頭最多有兩個能聽到它的臨近山頭。給定任意一個發出原始信號的山頭,本題請你找出這個信號最遠能傳達到的地方。
輸入第一行給出3個正整數n
、m
和k
,其中n
(≤10000)是總的山頭數(因而假設每一個山頭從1到n
編號)。接下來的m
行,每行給出2個不超過n
的正整數,數字間用空格分開,分別表明能夠聽到彼此的兩個山頭的編號。這裏保證每一對山頭只被輸入一次,不會有重複的關係輸入。最後一行給出k
(≤10)個不超過n
的正整數,數字間用空格分開,表明須要查詢的山頭的編號。
依次對於輸入中的每一個被查詢的山頭,在一行中輸出其發出的呼喊可以連鎖傳達到的最遠的那個山頭。注意:被輸出的首先必須是被查詢的個山頭能連鎖傳到的。若這樣的山頭不僅一個,則輸出編號最小的那個。若此山頭的呼喊沒法傳到任何其餘山頭,則輸出0。
這題也用廣搜思想,剛開始的時候這道題賊卡,以爲轉了一圈又回來那用什麼算法,什麼數據結構啊,隨後看了百度,而後從新寫了這篇博客,複習了一下選拔賽時候的優先隊列廣搜那道題,最後這道題用的鄰接表(這個說法當時百度聽得,當時賊迷,原來是讀進一個邊就把這個邊的兩個頂點都互相標記互爲鄰邊,後來在讀進一個點的時候就把這個點的鄰點(由於不知道幾個鄰點,要否則很差訪問,因此用vector存)都若沒有visit過就進入隊列,每一個node都包含num(哪一個點)和dep(第幾層)每作一次就判斷是否是最深的,由於數據賊小,就懶得優化了,每次判斷最深的各個哪一個最小就存哪一個,最後輸出。用隊列和BFS。
#include<iostream> #include<cstdio> #include<vector> #include<queue> using namespace std; struct node{ int num,dep; }; vector <int> a[10010]; int tot; void bfs(int n) { int maxx=0,minn=20000; bool visit[10010]; queue<node> q; node cur,next; for (int i=1;i<=tot;i++) visit[i]=0; cur.dep=1; cur.num=n; visit[n]=1; q.push(cur); while (!q.empty()) { cur=q.front(); q.pop(); for (int i=1;i<=a[cur.num].size();i++) { if (visit[a[cur.num][i-1]]==0) { visit[a[cur.num][i-1]]=1; next.num=a[cur.num][i-1]; next.dep=cur.dep+1; q.push(next); } if (next.dep==maxx) minn=min(minn,next.num); if (next.dep>maxx) { maxx=next.dep; minn=next.num; } } } if (maxx==0) cout<<0<<endl; else cout<<minn<<endl; } int main() { // freopen("test.in","r",stdin); // freopen("test.out","w",stdout); int m,k,u,v,x; cin>>tot>>m>>k; for (int i=1;i<=m;i++) { cin>>u>>v; a[u].push_back(v); a[v].push_back(u); } for (int i=1;i<=k;i++) { cin>>x; bfs(x); } }