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
posted @ 2015-11-06 22:24  gremount  阅读(300)  评论(0编辑  收藏  举报