欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-15 18:58:24
...
//源点到其余各点的最短路径
//从源点出发 遍历邻接点 每次选择最小的路径 作为次长 
#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;
}