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;
            }

        }

    }
}

 

 

 

 

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