PAT倒計時——6天!(圖篇)

還有六天就要考PAT了,這幾天寫博客回顧一下常用的算法,臨時抱一下佛腳哈哈哈~

第一次寫,如有錯誤,請多指教哈~

圖篇

甲級題庫中,感覺涉及到圖的題大部分用Dijkstra+DFS就可以AC了,部分題涉及到了拓撲排序和BFS。因此,這裏就只給出這四種簡單算法。

(下面代碼“/////////////////////////////////////////”以上的部分是全局變量,爲了查看方便寫到了函數中,有領結矩陣和領結表兩種寫法)

一、DFS

圖的深度遞歸沒啥好說的,注意不要走回頭路和遞歸邊界就好。


void DFS1(int index){

    int G[maxn][maxn];
    bool havego[maxn];

///////////////////////////////////////

    for(int i=0;i<maxn;i++){

        if(!havego[i]&&G[index][i]!=0){
            havego[i]=true;

            DFS1(i);
        }
    }
}


void DFS2(int index){

    vector<int> G[maxn];
    bool havego[maxn];

//////////////////////////////////////////////////

    for(int i=0;i<G[index].size;i++){
        int next=G[index][i];
        if(!havego[next]){

            havego[next]=true;

            DFS2(next);

        }

    }


}

二、Dijkstra

維護一個數組d[i](起點到 i 的最短距離),每次訪問經過最小距離能到達的下個結點,以該節點爲中間結點更新到達它下個的結點的最短距離。如果要求輸出最短路徑,維護一個數組pre[i](存放第 i 個結點的前置結點)。

如果有多個最短路徑,則先存放至vector<int> pre[i]中,再對其進行深度遍歷,遍歷過程中還可以計算其他條件(如最大點權和),具體內容參考晴神的算法筆記。這裏只給出最簡單的dij算法。

數據初始化:

d[s]=0;//邊權

c[s]=weight[s];//點權

pre[s]=s;//前置



void dijkstra1(int s){
    int G[maxn][maxn];
    int d[maxn];
    bool havego[maxn];

////////////////////////////////////////////////

    fill(d,d+maxn,inf);
    fill(havego,havego+maxn,false);

    d[s]=0;

    for(int i=0;i<n;i++){

        int cur=-1;
        int _min=inf;

        for(int j=0;j<n;j++){

            if(!havego[i]&&d[j]<_min){
                cur=i;
                _min=d[j];
            }

        }

        if(cur==-1)return;

        havego[cur]=true;

        for(int j=0;j<n;j++){

            if(!havego[j]&&G[cur][j]!=0&&G[cur]+G[cur][j]<d[j]){

                d[j]=G[cur]+G[cur][j];

            }

        }

    }

}

void dijkstra2(int s){

    struct node{
        int next;
        int distance;
    };

    vector<node> G[maxn];
    int d[maxn];
    bool havego[maxn];
////////////////////////////////////////////////////

    fill(d,d+maxn,inf);
    fill(havego,havego+maxn,false);

    d[s]=0;

    for(int i=0;i<n;i++){

        int cur=-1;
        int _min=inf;

        for(int j=0;j<n;j++){

            if(!havego[i]&&d[j]<_min){
                cur=i;
                _min=d[j];
            }

        }

        if(cur==-1)return;

        havego[cur]=true;

        for(int j=0;j<G[cur].size();j++){

            int next=G[cur][j].next;
            int dist=G[cur][j].distance;

            if(!havego[next]){

                if(d[cur]+dist<d[next]){

                    d[next]=d[cur]+dist;

                }

            }

        }


    }

}

三、拓撲排序

入度爲零加入隊列,每次將與當前結點相連的結點入度減一,如果爲零則入隊,最後訪問的節點數等於總結點數,則拓撲成功。

bool topologicalsort(){
    vector<int> G[maxn];
    int ver[maxn];//入度
//////////////////////////////////////////
    int ct=0;
    queue<int> Q;
    for(int i=0;i<n;i++){

        if(ver[i]==0)
            Q.push(i);
    }

    while(!Q.empty()){

        int cur=Q.front();
        Q.pop();

        for(int i=0;i<G[cur].size();i++){

            int next=G[cur][i];

            ver[next]--;

            if(ver[next]==0)
                Q.push(next);

        }

        ct++;
    }

    if(ct==n)
        return true;

    return false;

}

四、BFS

void BFS1(int index){

    int G[maxn][maxn];
    bool havego[maxn];

//////////////////////////////////////////////////////

    queue<int> Q;
    Q.push(index);

    havego[index]=true;
    while(!Q.empty()){

        int cur=Q.front();
        Q.pop();


        for(int i=0;i<maxn;i++){

            if(!havego[i]&&G[index][i]!=0){
                havego[i]=true;
                Q.push(i);
            }
        }

    }
}


void BFS2(int index){


vector<int> G[maxn];

bool havego[maxn];
///////////////////////////////////////////

    queue<int> Q;
    Q.push(index);
    havego[index]=true;
    while(!Q.empty()){
        int cur=Q.front();
        Q.pop();


        for(int i=0;i<G[cur].size();i++){
            int next=G[cur][i];
            if(!havego[next]){
                Q.push(next);
                havego[next]=true;
            }

        }

    }
}

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章