zoukankan      html  css  js  c++  java
  • 最短路径的三种实现方法

    //
    //  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;
    }
  • 相关阅读:
    Northwind数据库下载地址
    MSSQL跨服务访问数据库
    MSSQL基于一致性的I/O错误,解决方法之一
    DataGridView单元格ComboBox控件添加事件
    线程安全类 跨线程修改窗体UI
    数据库字段名
    SELECT INTO 和 INSERT INTO SELECT
    链表
    因为数据库正在使用,所以无法获得对数据库的独占访问权
    代替游标的循环
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5863681.html
Copyright © 2011-2022 走看看