图论-最短路-Dijkstra算法&Floyd算 c++

最短路径解决了求解一个图中两顶点之间最短的路径问题。其中Dijkstra算法应用贪心法求解单源点到其余各点的最短路径问题;而Floyd算法则解决了图中任意两点间的最短路径问题。

/*Dijkstra算法
时间复杂度O(n^2)
1.当前源点到任意点路径长度集合dist中的最短路径(v,vk)必为源点v到vk的最短路径,
因为源点v再经由其他点到vk必定比当前路径长度长
2.取min{(v,vi)当前长度,(v,vk)当前长度+(vk,vi)长度}为当前长度,反证法可知其贪心正确性
3.更新后将vk标记,下次不再查询
4.重复上述步骤直到每个点都查询一遍*/
struct vertex
{
    int v;
    string vex;
};
vertex Vertex[MAX];
int Groph[MAX][MAX];
void Dijkstra(int v, int n)
{
    vector<int> dist;//存储当前源点到任意点最短路长度
    vector<string> path;//存储当前源点到任意点最短路径
    vector<int> s;//存储源点与已经生成的终点的集合
    for (int i = 0; i < n; ++i)
    {
        dist.push_back(Groph[v][i]);
        if (dist[i] == INF)
            path.push_back(Vertex[v].vex + Vertex[i].vex);
        else
            path.push_back("");
    }
    s.push_back(v);
    dist[v] = 0;
    int num = 1;

    while (num < n)
    {
        int k = 0;
        for (int i = 0; i < n; ++i)
            if (dist[i] != 0 && dist[i] < dist[k])//找dist中的最小值k
                k = i;
        cout << dist[k] << " " << path[k] << endl;
        s.push_back(k);//加入集合s
        ++num;
        for (int i = 0; i < n; ++i)
        {
            if (dist[i]>dist[k]+Groph[k][i])//若源点经由k到其他点路径长度比当前路径长度小则修改dist和path
            {
                dist[i] = dist[k] + Groph[k][i];
                path[i] = path[k] + Vertex[i].vex;
            }
        }
        dist[k] = 0;//标记为已完成终点

    }

}
/*Floyd算法
时间复杂度O(n^3)
*/
struct vertex
{
    int v;
    string vex;
};
vertex Vertex[MAX];
int Groph[MAX][MAX];
void Floyd(int n)
{
    int dist[MAX][MAX];//distk[i][j]=min{dist(k-1)[i][j], dist(k-1)[i][k]+dist(k-1)[k][j]},0<=k<=n-1
    string path[MAX][MAX];
    for (int i = 0; i < n; ++i)//初始化dist和path
        for (int j = 0; j < n; ++j)
        {
            dist[i][j] = Groph[i][j];
            if (dist[i][j] != INF)
                path[i][j] = Vertex[i].vex + Vertex[j].vex;
            else
                path[i][j] = "";
        }
    for (int k = 0; k < n; ++k)//进行n次迭代
        for (int i = 0; i < n; ++i)//顶点i,j之间是否经过k点
            for (int j = 0; j < n; ++j)
                if (dist[i][k] + dist[k][j] < dist[i][j])
                {
                    dist[i][j] = dist[i][k] + dist[k][j];
                    path[i][j] = path[i][k] + path[k][j];
                }

    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            cout << path[i][j] << dist[i][j] << endl;
}

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/ymwtz/article/details/10033543
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞