隊列+BFS (附vector初試)

優先隊列的使用: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

Catch That Cow

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 a(10,1); //定義了10個整型元素的向量,且給出每一個元素的初值爲1
(3)vector a(b); //用b向量來建立a向量,總體複製性賦值
(4)vector a(b.begin(),b.begin+3); //定義了a值爲b中第0個到第2個(共3個)元素
(5)int b[7]={1,2,3,4,5,9,8};
vector a(b,b+7); //從數組中得到初值

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 a;
for(int i=0;i<10;i++)
a.push_back(i);

二、也能夠從數組中選擇元素向向量中添加

int a[6]={1,2,3,4,5,6};
vector b;
for(int i=1;i<=4;i++)
b.push_back(a[i]);

三、也能夠從現有向量中選擇元素向向量中添加

int a[6]={1,2,3,4,5,6};
vector b;
vector c(a,a+4);
for(vector ::iterator it=c.begin();it<c.end();it++)
b.push_back(*it);

四、也能夠從文件中讀取元素向向量中添加

ifstream in("data.txt");
vector a;
for(int i; in>>i)
a.push_back(i);

五、【誤區】

vector a;
for(int i=0;i<10;i++)
a[i]=i;

//這種作法以及相似的作法都是錯誤的。剛開始我也犯過這種錯誤,後來發現,下標只能用於獲取已存在的元素,而如今的a[i]仍是空的對象

(2)從向量中讀取元素
一、經過下標方式讀取

int a[6]={1,2,3,4,5,6};
vector b(a,a+4);
for(int i=0;i<=b.size()-1;i++)
cout<<b[i]<<" ";

二、經過遍歷器方式讀取

int a[6]={1,2,3,4,5,6};
vector b(a,a+4);
for(vector ::iterator it=b.begin();it!=b.end();it++)
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個正整數nmk,其中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);
    }
}
相關文章
相關標籤/搜索