最短路径的三种实现方法

//
//  main.cpp
//  helpbuptguoan
//
//  Created by New_Life on 16/8/24.
//  Copyright © 2016年 chenhuan001. All rights reserved.
//

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <map>
#include <random>
#include <algorithm>
using namespace std;

#define N 5 // 图的大小
const int TYPE = 3;/*用于设置图存储的数据结构,
                    1: 二维数组a[][]
                    2: 一维数组a[] 存放vector
                    3: map
                    */

const int INF = 1e3; //值上限

struct Graph{
    //第一种数据结构:二维数组
    int a1[N][N];
    //第二种数据结构
    vector< pair<unsigned int,unsigned char> >a2[N];
    //第三种
    map< pair<unsigned int,unsigned int>,unsigned char > a3;
    
    int s;//起点
    int length[N];//保存起点s到其他点的最短路
}G;

void init()//初始化,把每个数据结构都清空.
{
    G.a3.clear();
    for (int i=0; i<N; i++) {
        G.a2[i].clear();
        for(int j=0;j<N;j++){
            G.a1[i][j] = -1;//初始化不能到达,为-1
        }
    }
}

void add_edge(int u,int v){
    int w = rand()%10+1;
    if(TYPE == 1){
        G.a1[u][v] = w;
    }
    else if(TYPE == 2){
        pair<unsigned int,unsigned char> node;
        node.first = v;
        node.second = w;
        G.a2[u].push_back(node);
    }else{
        pair<unsigned int,unsigned int> node;
        node.first = u;
        node.second = v;
        G.a3[node] = w;
    }
}

void GetRandGraph()
{
    int tmpv[N];
    for(int i=0;i<N;i++)
    {
        int cnt=0;
        for(int j=0;j<N;j++)
        {
            if(j==i) continue;
            tmpv[cnt++] = j;
        }
        int tcnt = cnt;
        for(int j=0;j<min(tcnt,10);j++)//随机产生10个
        {
            int v = rand()%cnt;
            add_edge(i,tmpv[v]);
            for(int k=v;k<cnt-1;k++)//全体左移
            {
                tmpv[k] = tmpv[k+1];
            }
            cnt--;
        }
    }
}

void  Dijkstra()
{
    bool mark[N];
    for(int i=0;i<N;i++)
    {
        G.length[i] = INF;
        mark[i] = 0;
    }
    G.length[ G.s ] = 0;
    for(int t=0; t<N; t++)// N次循环
    {
        int mi = INF,id = -1;
        for(int i=0;i<N;i++)
        {
            if(mark[i] == 0 && G.length[i]<mi){//找出未标记的距离最小点
                mi = G.length[i];
                id = i;
            }
        }
        mark[id] = 1;
        if(TYPE == 1){
            for(int i=0;i<N;i++){
                if(G.a1[id][i]!=-1 && mark[i]==0 && mi+G.a1[id][i] < G.length[i])//三角不等式
                {
                    G.length[i] = mi+G.a1[id][i];//更新最小值
                }
            }
        }else if(TYPE == 2){
            for(int i=0;i<G.a2[id].size();i++){//遍历邻接表
                int v = G.a2[id][i].first;
                int w = G.a2[id][i].second;
                if(mark[v]==0 && mi+w < G.length[v])
                {
                    G.length[v] = mi+w;
                }
            }
        }else//type == 3
        {
            for(int i=0;i<N;i++){
                if(mark[i] == 0){
                    int w;
                    if( (w=G.a3[make_pair(id, i)])!=0 ){
                        G.length[i] = min(G.length[i],mi + w);
                    }
                }
            }
        }
    }
}

void print()
{
    //统一以邻接表形式输出图
    //
    if(TYPE == 2){
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<G.a2[i].size();j++)
                G.a1[i][ G.a2[i][j].first ] = G.a2[i][j].second;
        }
    }else if(TYPE == 3){
        for(int i=0;i<N;i++)
            for(int j=0;j<N;j++) if( G.a3[ make_pair(i, j) ]!=0 ) G.a1[i][j] =  G.a3[ make_pair(i, j) ];
    }
    printf("随机图的邻接表形式:
");
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            printf("%d	",G.a1[i][j]);
        }
        printf("
");
    }
    printf("////////////////////////
");
    printf("从0到各个节点的最短距离:
");
    printf("节点:");
    for(int i=0;i<N;i++) printf("%d ",i);
    printf("
");
    printf("距离:");
    for(int i=0;i<N;i++){
        printf("%d ",G.length[i]);
    }
    printf("
");
}
int main(int argc, const char * argv[]) {
    init();//初始化
    GetRandGraph();
    Dijkstra();
    print();//打印图信息
    
    return 0;
}
原文地址:https://www.cnblogs.com/chenhuan001/p/5863681.html