算法-dijkstra求最短路径(邻接表实现)

差不多算是第一个了解的算法,主要是做pat甲级时要用,依照的是《数据结构与算法分析》这本书;

之前本来就想用lis作为链表,但是貌似只能存一个数据,存不了权,只能自己建链表做了,最近看到pair,也不知道这么用对不对

试着写写,之后等再深入了解c++后再回来看看吧。

题目 : https://www.patest.cn/contests/pat-a-practise/1003

/*dijkstra算法求最短路径 邻接表表示图**/
#include <iostream>
#include <list>
#include <utility>
#include <iterator>
#define NotAVertex (-1)
#define INF (1<<30)
#define MAX 500

using namespace std;

static int numvertex, start;

typedef struct TableEntry
{
    list< pair<int,int> > mylist;
    bool known;
    int dist;
    int path;
}adjacency_list;

adjacency_list graph[MAX];

void graph_init()
{
    int v, w;
    int i;
    for(i=1; i<=numvertex; i++)
    {
        graph[i].dist = INF;
        graph[i].known = false;
        graph[i].path = NotAVertex;
    }
    graph[start].dist = 0;
    for(i=1; i<=numvertex; i++)
    {
        cout << "输入顶点" << i << "的邻接点及其权值" << endl;
        //"windows下输入回车后输入ctrl+z linux下输入ctrl+d结束输入"
        while(cin >> v >> w)
        {
            graph[i].mylist.push_back(make_pair(v, w));//fisrt表示顶点,second表示权;
        }
        cin.clear();
    }
}

void dijkstra()
{
    int i, j, mindist, key;
    list< pair<int, int> >::iterator it;
    for(i=1; i<=numvertex; i++)
    {
        mindist = INF;
        for(j=1; j<=numvertex; j++)
        {
            if(!graph[j].known && graph[j].dist<mindist)
            {
                mindist = graph[j].dist;
                key = j;
            }
        }
        graph[key].known = true;
        for(it=graph[key].mylist.begin(); it!=graph[key].mylist.end(); it++)
        {
            if(!graph[it->first].known)
            {
                if(it->second+mindist < graph[it->first].dist)
                {
                    graph[it->first].dist = it->second+mindist;
                    graph[it->first].path = key;
                }
            }
        }

    }
}

void print_path(int end_vertex)
{
    if(graph[end_vertex].path != NotAVertex)
    {
        print_path(graph[end_vertex].path);
        cout << "到";
    }
    cout << end_vertex;
}

int main()
{
    cout << "输入顶点的数量和所求最短路径的起点" << endl;
    cin >> numvertex >> start;
    graph_init();
    dijkstra();
    for(int i=1; i<=numvertex; i++)
    {
        cout << "地点" << start << "到地点" << i << "的最短路径路线为:" << endl;
        print_path(i);
        cout  <<  endl << "最短路径长为" << graph[i].dist << endl << endl;
    }
    return 0;
}

附上之前写的

/*dijkstra算法求最短路径 邻接表表示图**/
#include <iostream>
#define NotAVertex (-1)
#define INF (1<<30)
#define MAX 500

using namespace std;

static int numvertex, start;
typedef struct NODE
{
    int adjvex;
    int weight;
    struct NODE *next;
}Node;

typedef struct TableEntry
{
    Node *header;
    bool known;
    int dist;
    int path;
}adjacency_list;

adjacency_list graph[MAX];

void graph_init()
{
    int v, w;
    int i;
    Node *p;
    for(i=1; i<=numvertex; i++)//初始化图数据
    {
        graph[i].dist = INF;
        graph[i].known = false;
        graph[i].path = NotAVertex;
        graph[i].header = NULL;
    }
    graph[start].dist = 0;//起始节点最短距离为0;
    for(i=1; i<=numvertex; i++)
    {
        cout << "输入顶点" << i << "的邻接点及其权值" << endl;
        //"windows下输入回车后输入ctrl+z linux下输入ctrl+d结束输入"
        while(cin >> v >> w)//头插法创建链表
        {
            p = new Node;
            p->adjvex = v;
            p->weight = w;
            p->next = graph[i].header;
            graph[i].header = p;
        }
        cin.clear();
    }
}

void dijkstra()
{
    int i, j, mindist, key;
    Node *p = NULL;
    for(i=1; i<=numvertex; i++)
    {
        mindist = INF;
        for(j=1; j<=numvertex; j++)//求当前未知的最短距离点
        {
            if(!graph[j].known && graph[j].dist<mindist)
            {
                mindist = graph[j].dist;
                key = j;
            }
        }
        graph[key].known = true;//标记已知
        p = graph[key].header;//指向该点内链表表头
        while(p != NULL)
        {
            if(!graph[p->adjvex].known)
            {
                if(p->weight+mindist < graph[p->adjvex].dist)//如果key点邻接点的已知最小距离比key点到邻接点距离加上key到基点最短距离要大则更新
                {
                    graph[p->adjvex].dist = p->weight+mindist;
                    graph[p->adjvex].path = key;//标记该邻接点最短距离的前位点为key点
                }
            }
            p = p->next;
        }
    }
}

void print_path(int end_vertex)
{
    if(graph[end_vertex].path != NotAVertex)
    {
        print_path(graph[end_vertex].path);//递归遍历前位点,输入路径
        cout << "到";
    }
    cout << end_vertex;
}

int main()
{
    cout << "输入顶点的数量和所求最短路径的起点" << endl;
    cin >> numvertex >> start;
    graph_init();
    dijkstra();
    for(int i=1; i<=numvertex; i++)
    {
        cout << "地点" << start << "到地点" << i << "的最短路径路线为:" << endl;
        print_path(i);
        cout  <<  endl << "最短路径长为" << graph[i].dist << endl << endl;
    }
    return 0;
}

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