源点到所有顶点的最短路径

//源点到其余各点的最短路径
//从源点出发 遍历邻接点 每次选择最小的路径 作为次长 
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#define MAXSIZE 256

struct BaseNode
{
    BaseNode(){
        tailIndex = -1;
        nWeight = -1;
        Next = NULL;
    }
    int tailIndex;
    int nWeight;
    BaseNode * Next;
};

struct GraphNode
{
    GraphNode(){
        info = '\0';
        first = NULL;
    }
    char info;
    BaseNode * first;
};

class Graph
{
public:
    Graph()
    {
        m_VertSize = -1;
        m_EdgeSize = -1;
    }
public:
    bool Init();
    void FindMin(int nStart);
public:
    GraphNode m_Node[MAXSIZE];

    int m_VertSize;

    int m_EdgeSize;
};


bool Graph::Init()
{
    cout << "输入节点数" << endl;
    cin >> m_VertSize;
    for (int i = 1; i <= m_VertSize; i++)
    {
        char info;
        cin >> info;
        m_Node[i].info = info;
    }
    cout << "输入边数" << endl;
    cin >> m_EdgeSize;
    for (int i = 1; i <= m_EdgeSize; i++)
    {
        int nHead, nTail, nWeight;
        cin >> nHead >> nTail >> nWeight;
        if (m_Node[nHead].first == NULL)
        {
            m_Node[nHead].first = new BaseNode;
            m_Node[nHead].first->tailIndex = nTail;
            m_Node[nHead].first->nWeight = nWeight;
        }
        else{
            BaseNode* t = m_Node[nHead].first;
            while (t && t->Next )
            {
                t = t->Next;
            }
            t->Next = new BaseNode;
            t->Next->tailIndex = nTail;
            t->Next->nWeight = nWeight;
        }
    }
    return true;
}

struct MinPath
{
    MinPath()
    {
        index = -1;
        path = "";
        nLength = -1;
    }
    int index;
    int nLength;
    string path;
    bool operator==(int a)
    {
        return a == index;
    }
};
void Graph::FindMin(int nStart)
{
    //nStart 到其他各点 情况初始化
    vector<MinPath> allPath;
    for (int i = 1; i <= m_VertSize; i++)
    {
        if (i != nStart)
        {
            MinPath p;
            p.index = i;
            allPath.push_back(p);
        }
    }

    //从源点开始
    vector<int> selectPoint,hasSelected;
    selectPoint.push_back(nStart);
    while (selectPoint.size() > 0)
    {

        int p = selectPoint[0];
        //标记该点已选
        hasSelected.push_back(p);
        selectPoint.erase(selectPoint.begin());

        //第一个邻接点
        BaseNode * t = m_Node[p].first;

        //记录 该点 当前 路径 和长度
        string info="";
        int nLength = 0;
        vector<MinPath>::iterator name = find(allPath.begin(), allPath.end(), p);
        if (name == allPath.end() || (*name).path == "")
        {
            info = m_Node[p].info;
            nLength = 0;
        }
        else{
            info = (*name).path;
            nLength = (*name).nLength;
        }

        //遍历邻接点 替换最小 路径
        while (t)
        {
            vector<MinPath>::iterator it = find(allPath.begin(), allPath.end(), t->tailIndex);
            if (it != allPath.end())
            {
                if ((*it).nLength == -1 || ( (*it).nLength > t->nWeight + nLength ))
                    {
                        (*it).nLength = t->nWeight + nLength;
                        (*it).path = info;
                        (*it).path += m_Node[t->tailIndex].info;
                    }
            }
            t = t->Next;
        }

        int m = -1, n = -1;
        //从未选过的点中 选择路径最短的点
        for (int i = 0; i < allPath.size(); i++)
        {
            if (find(hasSelected.begin(), hasSelected.end(), allPath[i].index) == hasSelected.end())
            {
                if (allPath[i].nLength != -1 && ((m == -1 || m > allPath[i].nLength) ))
                {
                    m = allPath[i].nLength;
                    n = allPath[i].index;
                }
            }
        }
        if (n != -1)
        selectPoint.push_back(n);
    }


    for (int i = 0; i < allPath.size(); i++)
    {
        cout << allPath[i].path << allPath[i].nLength << endl;
    }
}

int main()
{
    Graph g;
    if (g.Init())
    {
        g.FindMin(1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/seanbill/article/details/80158122