• C++的面向对象的Dijkstra写法


    C++的面向对象的Dijkstra写法

    • 面向对象特点的充分使用
    • 清晰的逻辑
    • 简洁的图输入
    • 程序

    面向对象特点的充分使用

    清晰明确的类实现
    class Edge(边的实现)
    class Req (路由请求的实现)
    class Graph (图的实现)
    其中将Dijkstra算法放置在Graph里,方便调用
    这里的邻接矩阵将会存放真正的边信息,而不再仅仅存放边的权值
    Req信息包含src, dst, flow, 其中flow是流的大小
    Edge信息包含src,dst,weight,capacity

    清晰的逻辑

    在Dijkstra算法实现的时候将Update操作和FindMin操作分别提出来当做独立的函数,这将使得Dijkstra算法函数的思路很清晰

    简洁的图输入

    在图的构造函数处,使用文件操作,来读入图,然后将边的信息存入如下三个vector类型的数据结构里,使用起来会非常方便:

        vector<Edge*> incL;//所有的边
        vector<vector<Edge*> > adjL;//正向邻接表
        vector<vector<Edge*> > adjRL;//反向邻接表

    程序

    程序由三部分构成:

    common.h 程序用到的所有库的头文件和常量声明
    resources.h 三个类的定义
    main.cpp 主程序
    graph.txt 图

    common.h

    #define COMMON_H
    
    #include<iostream>
    #include<vector>
    #include<math.h>
    #include<list>
    #include<set>
    #include<stdio.h>
    #include<fstream>
    using namespace std;
    
    #define MAXNODE 100;
    #define INF 999999;
    #endif
    

    resources.h

    #ifndef RESOURCES_H
    #define RESOURCES_H
    
    #include"common.h"
    
    class Edge{
    public:
        int id, src, dst, weight, capacity;
        Edge(int a, int b, int c, int d, int e){
            id = a; src = b; dst = c; weight = d; capacity = e;
        }
    };
    
    class Req{
    public:
        int src, dst, flow;
        Req(int a, int b, int c){
            src = a; dst = b; flow = c;
        }
    };
    
    class Graph{
    public:
        int n, m;
        set<int> S, V;
        vector<int> d, p;
        vector<Edge*> incL;
        vector<vector<Edge*> > adjL;
        vector<vector<Edge*> > adjRL;
        Graph(string s){
            ifstream infile(s);
            infile >> n >> m;
            int temp;
            temp = m;
            m = m * 2;
            adjL.resize(n);
            adjRL.resize(n);
            d.resize(n);
            p.resize(n);
            int a, b, c, d;
            for (int i = 0; i < temp;i++){
    
                infile >> a >> b >> c >> d;
                Edge* e1 = new Edge(i * 2, a, b, c, d);
                Edge* e2 = new Edge(i * 2 + 1, b, a, c, d);
    
                incL.push_back(e1); incL.push_back(e2);
                adjL[a].push_back(e1); adjL[b].push_back(e2);
                adjRL[b].push_back(e1); adjRL[a].push_back(e2);
            }
        }
    
        void Update(int s){
            for (int i = 0; i < adjL[s].size();i++)
                if (d[s] + adjL[s][i]->weight < d[adjL[s][i]->dst]){
                    d[adjL[s][i]->dst] = d[s] + adjL[s][i]->weight;
                    p[adjL[s][i]->dst] = s;
                }
        }
    
        int FindMin(){
            set<int>::iterator it, iend;
            iend = S.end();
            int mine = INF;
            int min_node = -1;
            for (it = S.begin(); it != iend; it++){
                if(d[*it] < mine) {
                    mine = d[*it];
                    min_node = *it;
                }
            }
            return min_node;
        }
    
        void dijkstra(int src, int dst){
            S.clear();
            V.clear();
            for (int i = 0; i < n; i++)
            {
                S.insert(i);
                d[i] = INF;
                p[i] = -2;
            }
            d[src] = 0; p[src] = -1;
            Update(src);
            S.erase(src);
            V.insert(src);
            while (S.size() != 0)
            {
                int mind;
                mind = FindMin();
                if (mind == dst) break;
                Update(mind);
                S.erase(mind);
                V.insert(mind);
            }
            cout << "from node " << src << " to node " << dst << ": " << d[dst]<<endl;
        }
    };
    
    #endif

    main.cpp

    #include"common.h"
    #include"resources.h"
    
    int main()
    {
        Graph g("graph.txt");
    
        g.dijkstra(1, 16);
    
        cout << "happy" << endl;
    
        getchar();
        return 0;
    }

    graph.txt

    18 21
    1 17 1 10
    1 2 1 20
    2 17 1 20
    1 3 1 30
    3 4 1 30
    4 17 1 30
    1 5 1 40
    5 6 1 40
    6 7 1 40
    7 17 1 40
    1 8 1 50
    8 9 1 50
    9 10 1 50
    10 11 1 50
    11 17 1 50
    1 12 1 100
    12 13 1 100
    13 14 1 100
    14 15 1 100
    15 16 1 100
    16 17 1 100
  • 相关阅读:
    nginx获取上游真实IP(ngx_http_realip_module)
    配置NFS固定端口
    elasticsearch 占CPU过高
    jdk集合常用方法分析之HashSet和TreeSet
    SparkSQL使用之如何使用UDF
    SparkSQL使用之JDBC代码访问Thrift JDBC Server
    SparkSQL使用之Thrift JDBC server
    SparkSQL使用之Spark SQL CLI
    jdk分析之String
    jdk集合常用方法分析之ArrayList&LinkedList&以及两者的对比分析
  • 原文地址:https://www.cnblogs.com/gremount/p/5768010.html
Copyright © 2020-2023  润新知