用广度优先遍历求有向带权图的最短路径

graph.h

#ifndef GRAPH_H
#define GRAPH_H

#include<vector>

using namespace std;

class edge;

class vertex		//顶点
{
    friend void connect ( vertex& , vertex& , int );		//建立关系
    friend void bfs (const vertex& , int );					//广度遍历
    friend void bfs ( vertex& , vertex& , int n );
public:
    bool operator!=( const vertex& );
    vertex *pPre = nullptr;					//用于记录路径,指向第一个到达该顶点的顶点。
    int ID = 0;										//顶点的独一无二的序号,构造时给定。

private:
    int in_degree = 0;							//入度
    int out_degree = 0;						//出度
    vector<edge> incident_edge;		//关联边的集合

};

class edge				//边
{
    friend void connect ( vertex& , vertex& , int );
    friend void bfs ( const vertex& , int );
    friend void bfs ( vertex& , vertex& , int n );
public:
    edge ( vertex& , int );
private:
    int weight = 0;				//权重
    vertex* pNext = nullptr;		//指向的顶点
};

#endif

graph.cpp

#include"graph.h"

edge::edge ( vertex& v , int w )
{
    weight = w;
    pNext = &v;
}

void connect ( vertex& v1 , vertex& v2 , int w )
{
    v1.out_degree++;
    v2.in_degree++;
    edge e ( v2 , w );
    v1.incident_edge.push_back ( e );
}

bool vertex::operator!=( const vertex& v)
{
    return this->ID != v.ID;
}

main.cpp

#include<iostream>
#include<map>
#include<deque>

#include"graph.h"

using namespace std;

map<int , vertex> s;		//顶点的集合
deque<vertex> pre;			//顶点的集合,用于记录前一个顶点
deque<vertex> qv;			//顶点的队列
deque<int> qi;					//离顶点距离的队列
deque<vertex> path;		//记录路径的队列

void bfs ( const vertex& , int );		//第一次没有前驱的广度遍历
void bfs ( vertex& , vertex& , int n );		//广度遍历

int main ( void )
{
    //建立图
    int n;
    cout << "请输入边的数量" << endl;
    cin >> n;
    cout << "请输入边的弧尾、弧头和权重" << endl;
    for ( int i = 0; i < n; i++ )
    {
        int a , b , c;
        cin >> a >> b >> c;
        s [ a ].ID = a;
        s [ b ].ID = b;
        connect ( s [ a ] , s [ b ] , c );
    }
    cout << "请输入起始顶点和结束顶点" << endl;
    int a , b;
    cin >> a >> b;

    bfs ( s [ a ] , 0 );		//启动BFS

    //广度遍历直到到达终点
    while (s[b].pPre==nullptr)
    {
        bfs (pre[0], qv [ 0 ] , qi [ 0 ] );
        pre.pop_front ();
        qv.pop_front ();
        qi.pop_front ();
    }
    qv.clear ();
    qi.clear ();
    pre.clear ();
    for ( vertex * i = &s [ b ]; i != nullptr; i = i->pPre )
    {
        path.push_front ( *i );
    }
    for ( auto &i : path )
    {
        cout << i.ID << " ";
    }
    cout << endl;
    system ( "pause" );
    return 0;
}

void bfs ( const vertex& v , int n )
{
    if ( n == 0 )	//到达下一个顶点时
    {
        for ( auto &i : v.incident_edge )
        {
            qv.push_back ( *( i.pNext ) );
            qi.push_back ( i.weight );
            pre.push_back ( v );
        }
        return;
    }

    if ( n != 0 )	//未到达下一个顶点时
    {
        qv.push_back ( v );
        qi.push_back ( n - 1 );
        return;
    }
}

void bfs ( vertex& v1 , vertex& v2 , int n )
{
    if ( n == 0 )	//到达下一个顶点时
    {
        if ( s[v2.ID].pPre == nullptr )
        {
            s[ v2.ID ].pPre = &s[v1.ID];
        }

        for ( auto &i : v2.incident_edge )
        {
            qv.push_back ( *( i.pNext ) );
            pre.push_back ( v2 );
            qi.push_back ( i.weight );
        }
        return;
    }

    if ( n != 0 )	//未到达下一个顶点时
    {
        qv.push_back ( v2 );
        pre.push_back ( v1 );
        qi.push_back ( n - 1 );
        return;
    }
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/wzh190015/article/details/50301055
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞