数据结构之最短路径的 Dijkstra Algorithm && Floyd Algorithm

来源:互联网 发布:苏州远洋数据 编辑:程序博客网 时间:2024/05/16 01:07

没有什么说的。代码中讲解的应该还算明确。

但是我想说的是一定要把最短路径和最小生成树给分开。。最小生成树是求一个Graph(这个图中必定是全部联通图)中,求解所有子树中所有路径之和最小的子树。。而最短路径则求Graph中是从一个点到另一个点路径之和最短的路径。这完全是两个问题。。没有任何联系!

#include <iostream>#include <cstdio>#include <string>#include <cmath>#include <algorithm>#include <cstring>#include <map>#include <queue>#include <stack>#define INF 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a));#define For(a,b) for(int i = a;i<b;i++)#define LL long long#define MAX_N 100010#define VN 10using namespace std;typedef int Vextype;typedef int Adjtype;typedef int Elemtype;typedef struct{    Vextype vexs[VN];    Adjtype arcs[VN][VN];}Graph; //邻接矩阵的存储结构typedef struct{    Adjtype length;    int prevex;}Path;//Dijkstra算法中的操作对象typedef struct{    Adjtype weight[VN][VN];    int nextVex[VN][VN];}ShortPath;//Floyd算法中的操作对象Elemtype Dijk_flag = 1;//判断该点是否到所有点都有通路的标志Elemtype mark[VN][VN];//记录原始邻接矩阵的数据元素/*    初始化Dijkstra algorithm中的dis数组。    其实也就是将0到Graph中所有的点的距离    以及所有点的前驱(0),置于dis数组    如果说没有通路。则置为-1。*/void init(Graph * graph,Path dis[],Elemtype node_num){    dis[0].length = 0;    dis[0].prevex = 0;    graph->arcs[0][0] = 1;    for(int i = 1; i<node_num; i++)    {        dis[i].length = graph->arcs[0][i];        if(dis[i].length != MAX_N)        {            dis[i].prevex = 0;        }        else            dis[i].prevex = -1;    }}void Dijkstra(Graph * pgraph,Path dis[],Elemtype node_num){    init(pgraph,dis,node_num);    int minw,minVex;    /*        这个for循环每循环一次找到一个        距离初始点的最短距离的点    */    for(int i = 1; i<node_num; i++)    {        minw = MAX_N;        minVex = 0;        /*            该for循环是为了找到当前dis数组中最小的length值        */        for(int j = 1; j<node_num; j++)        {            if(pgraph->arcs[j][j] == 0 && dis[j].length < minw)            {                minw = dis[j].length;                minVex = j;            }        }        /*            此判断是该Graph是否所有的点可以连成一个通路            如果不能·则用全局变量Dijk_flag标记        */        if(minVex == 0)        {            Dijk_flag = 0;            break;        }        pgraph->arcs[minVex][minVex] = 1;        /*            更新dis数组中剩下的元素中的前驱和length值        */        for(int j = 1; j<node_num; j++)        {            if(pgraph->arcs[j][j] == 0 && dis[j].length > dis[minVex].length + pgraph->arcs[minVex][j])            {                dis[j].length = dis[minVex].length + pgraph->arcs[minVex][j];                dis[j].prevex = minVex;            }        }    }}void Floyd(Graph *pgraph,ShortPath *ppath,Elemtype node_num){    /*        初始化ppath结构体中的数组元素。        如果从i点到j点有通路,则nextVex[i][j] = j;        否则等于-1。        不论是否有通路,都将weight值赋予weight[i][j].    */    for(int i = 0; i<node_num; i++)    {        for(int j = 0; j<node_num; j++)        {            if(pgraph->arcs[i][j] != MAX_N)            {                ppath->nextVex[i][j] = j;            }            else                ppath->nextVex[i][j] = -1;            ppath->weight[i][j] = pgraph->arcs[i][j];        }    }    /*        每次外层循环k不变,就相当于喜欢是每次将k点插入i到j的路径当中去。        这样遍历一遍求最短Graph中可以连通的点中。每两个点之间的最短路径。    */    for(int k = 0; k<node_num; k++)        for(int i = 0; i<node_num; i++)            for(int j = 0 ; j<node_num; j++){                if(ppath->weight[i][k] >= MAX_N || ppath->weight[k][j] >= MAX_N)                    continue;                if(ppath->weight[i][j] > ppath->weight[i][k] + ppath->weight[k][j])                {                    ppath->weight[i][j] = ppath->weight[i][k] + ppath->weight[k][j];                    ppath->nextVex[i][j] = ppath->nextVex[i][k];                }            }}int main(){    Graph pgraph;    Path dis[VN];    ShortPath shpath;    int node_num = 6;    int edge_num = 11;    for(int i = 0; i<node_num; i++)    {        for(int j = 0; j<node_num; j++){            if(i==j) mark[i][j] = 0;            else mark[i][j] = MAX_N;        }    }    int node_start,node_stop,edge_val = 0;    for(int i = 0; i<edge_num; i++)    {        cin>>node_start>>node_stop>>edge_val;        mark[node_start][node_stop] = edge_val;    }    /*        为arcs邻接矩阵数组赋初值    */    for(int i = 0; i<node_num; i++)    {        for(int j = 0; j<node_num; j++)        {            pgraph.arcs[i][j] = mark[i][j];        }    }    Dijkstra(&pgraph,dis,node_num);    if(Dijk_flag)    {        cout<<"该图中所有的结点连通,且这是一个连通图。"<<endl<<endl;    }    else        cout<<"这个图中存在不可访问到的结点,所以这不是一个连通图。"<<endl<<endl;    cout<<"1 — 0的最短路径长度是: "<<endl<<dis[1].length<<endl<<endl;    cout<<"1 — 0的最短路径是:"<<endl;    cout<<"V_1 -> ";    int prev = 1;    while(1)    {        prev = dis[prev].prevex;        cout<<"V_"<<prev<<" -> ";        if(prev == 0)        {            cout<<endl<<endl;            break;        }    }    /*        由于经过Dijkstra算法的调用,arcs数组中一些元素已被改变。        所以需要再次对arcs数组进行初始化。    */    for(int i = 0; i<node_num; i++)    {        for(int j = 0; j<node_num; j++)        {            pgraph.arcs[i][j] = mark[i][j];        }    }    Floyd(&pgraph,&shpath,node_num);    cout<<"0 — 1的最短路径长度是: "<<endl<<shpath.weight[0][1]<<endl<<endl;    cout<<"0 — 1的最短路径是:"<<endl;    cout<<"V_0 -> ";    int next = shpath.nextVex[0][1];    while(1)    {        cout<<"V_"<<next<<" -> ";        next = shpath.nextVex[next][1];        if(next == 1)        {            cout<<"V_1"<<endl<<endl;            break;        }    }    //system("pause");    return 0;}/*2016.10.7测试样例:0 1 500 2 100 4 451 2 151 4 52 0 202 3 153 1 203 4 354 3 305 3 3*/



0 0
原创粉丝点击