最主要的Vertex类:

#ifndef VERTEX_H
#define VERTEX_H #include <climits>
#include <cstddef>
#define INF INT_MAX class Vertex
{
public:
int ID;
Vertex* parent;
int d; Vertex(int id) : ID(id), d(INF), parent(NULL){}
}; #endif

接下来是Edge类:

#ifndef EDGE_H
#define EDGE_H #include "vertex.h" class Edge
{
private:
float weight;
float capacity;
float passrate; public:
int id;
Vertex* tail;
Vertex* head;
/******** constructor *******/
Edge(int ID, Vertex& t, Vertex& h, float wght = 1,
float cap = 1, float pssrt = 1) :
id(ID), head(&h), tail(&t), weight(wght),
capacity(cap), passrate(pssrt) {} /********** The ID **********/
void setId(int ID)
{
id = ID;
}
int getId()
{
return id;
} /********* The vertex ********/
void setTail(Vertex& v)
{
tail = &v;
}
void setHead(Vertex& v)
{
head = &v;
} /******** Other method *******/
void setWeight(const float w)
{
weight = w;
}
float getWeight()
{
return weight;
}
float getCapacity()
{
return capacity;
}
float getPassRate()
{
return passrate;
} }; #endif

当然还有路问题须要的Path类:

#ifndef PATH_H
#define PATH_H #include <list>
#include "vertex.h" class Path : std::list<Vertex*>
{
public:
Path(Vertex& tail); void print();
}; #endif

这是Path类的实现:

#include "path.h"
#include <iostream>
#include "vertex.h"
#include <list> using namespace std; Path::Path(Vertex& tail)
{
Vertex* temp = &tail;
while (temp->parent != NULL)
{
push_back(temp);
temp = temp->parent;
}
push_back(temp);
} void Path::print()
{
reverse();
list<Vertex*>::iterator it;
it = begin();
cout << "Vertex " << (*it)->ID;
it++;
for (; it != end(); it++)
cout << " -> Vertex " << (*it)->ID;
}

下来就是最重要也是最复杂的Graph类了!

#ifndef GRAPH_H
#define GRAPH_H #include <map>
#include "edge.h"
#include "vertex.h"
#include "path.h"
#include <set>
#include <list> class Graph
{
std::map<int, Vertex*> vertexMap;
// The map: vertex and its incident edge.
std::map<Vertex*, std::list<Edge*> > incMap;
std::set<Edge*> edgeList;
std::list<Vertex*> notMarkedVertex;
bool fromFile;
Path* path; void update(Vertex* v); public:
/********** constructor *********/
Graph(): fromFile(false){}
Graph(const char* inputFileName);
Graph(std::list<Edge*>& edge);
~Graph(); /*********** size info **********/
int getNumVertex()
{
return vertexMap.size();
}
int getNumEdge()
{
return edgeList.size();
} void print();
void addEdge(Edge& edge);
void dijkstra(int s, int d);
void dijkstra(Vertex& s, Vertex& d);
}; #endif

下来是实现:

#include "graph.h"
#include <iostream>
#include <fstream>
#include <map>
#include <set>
#include <list>
#include <string>
#include <cstdlib> using namespace std; Graph::Graph(const char* inputFileName)
{
fromFile = true;
ifstream in(inputFileName); string s;
getline(in, s);
getline(in, s); while (in.good())
{
int id, tail, head;
float weight, capacity, passrate;
in >> id >> tail >> head
>> weight >> capacity >> passrate;
map<int, Vertex*>::iterator it;
it = vertexMap.find(tail); Vertex *t;
Vertex *h; if (it == vertexMap.end())
t = new Vertex(tail);
else
t = it->second; it = vertexMap.find(head);
if (it == vertexMap.end())
h = new Vertex(head);
else
h = it->second; Edge* e = new Edge(id, *t, *h, weight, capacity, passrate);
addEdge(*e);
}
} Graph::Graph(list<Edge*>& edge)
{
list<Edge*>::iterator it;
for (it = edge.begin(); it != edge.end(); it++)
addEdge(**it);
fromFile = false;
} void Graph::addEdge(Edge& edge)
{
edgeList.insert(&edge);
vertexMap.insert(pair<int, Vertex*>(edge.tail->ID, edge.tail));
vertexMap.insert(pair<int, Vertex*>(edge.head->ID, edge.head)); if (incMap.find(edge.tail) == incMap.end())
{
list<Edge*>* l = new list<Edge*>(1, &edge);
incMap.insert(pair<Vertex*, list<Edge*> >(edge.tail, *l));
}
else
incMap.find(edge.tail)->second.push_back(&edge);
} void Graph::print()
{
map<Vertex*, list<Edge*> >::iterator it;
list<Edge*>::iterator it2;
for (it = incMap.begin(); it != incMap.end(); it++)
{
cout << "Vertex " << it->first->ID << endl;
for (it2 = it->second.begin();
it2 != it->second.end();
it2++)
cout << "\tEdge " << (*it2)->id << " to Vertex "
<< (*it2)->head->ID << endl;
}
} Graph::~Graph()
{
if (fromFile)
{
set<Edge*>::iterator it;
for (it = edgeList.begin();
it != edgeList.end();
it++)
delete *it; map<int, Vertex*>::iterator it2;
for (it2 = vertexMap.begin();
it2 != vertexMap.end();
it2++)
delete it2->second;
}
} bool comp(Vertex* a, Vertex* b)
{
return a->d < b->d;
} void Graph::update(Vertex* v)
{
list<Edge*> inc = incMap[v];
if (inc.size() == 0)
{
cerr << "No out degree!" << endl;
exit(EXIT_FAILURE);
} list<Edge*>::iterator it;
for (it = inc.begin(); it != inc.end(); it++)
{
int d = v->d + (*it)->getWeight();
if ((*it)->head->d > d)
{
(*it)->head->parent = v;
(*it)->head->d = d;
}
}
} void Graph::dijkstra(int sid, int did)
{
Vertex* s = vertexMap[sid];
Vertex* temp;
s->d = 0; map<int, Vertex*>::iterator it;
for (it = vertexMap.begin();
it != vertexMap.end();
it++)
if (it->second->ID != sid)
notMarkedVertex.push_back(it->second);
update(s); do
{
notMarkedVertex.sort(comp);
temp = notMarkedVertex.front();
notMarkedVertex.pop_front();
if (temp->ID == did)
break;
update(temp);
}while(!notMarkedVertex.empty()); path = new Path(*vertexMap[did]);
path->print();
} void Graph::dijkstra(Vertex& s, Vertex& d)
{
dijkstra(s.ID, d.ID);
}

眼下的工作就是这些了。

以下是一个測试程序:

test.cpp:

#include <iostream>
#include "graph.h"
#include "path.h" using namespace std; int main()
{
Graph graph("InputFile.txt");
graph.print(); cout << "Please input the s and d: ";
int s, d;
cin >> s >> d;
graph.dijkstra(s, d); return 0;
}

还有InputFile.txt 的内容:

n 7
e 9
1 1 2 1 20 0.8
2 2 3 5 30 0.8
3 3 6 6 22 0.6
4 7 6 5 22 0.4
5 1 7 3 20 0.2
6 5 6 2 20 0.3
7 3 5 1 20 0.5
8 4 5 6 20 0.6
9 2 4 2 20 0.7

最后是执行结果了!

通信网Project之——单源单宿最短路问题的更多相关文章

  1. Vijos 1006 晴天小猪历险记之Hill 单源单汇最短路

    背景 在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结-- 不过有一天,最小的小小猪生病了,而这种病是极其罕见的,因此大家都没有储存这种药物.所以晴天小猪自告奋勇 ...

  2. 单源最短路问题:OJ5——低德地图

    本题就是一道单源最短路问题.由于是稀疏图,我们采用Dijkstra算法. Dijkstra算法原理 Dijkstra算法的步骤 我们把所有的节点分为两个集合:被选中的(visited==1) 和 未被 ...

  3. [ACM_图论] Domino Effect (POJ1135 Dijkstra算法 SSSP 单源最短路算法 中等 模板)

    Description Did you know that you can use domino bones for other things besides playing Dominoes? Ta ...

  4. UVa 12661 (单源最短路) Funny Car Racing

    题意: 有一个赛车跑道,可以看做一个加权有向图.每个跑道(有向边)还有一个特点就是,会周期性地打开a秒,然后关闭b秒.只有在赛车进入一直到出来,该跑道一直处于打开状态,赛车才能通过. 开始时所有跑道处 ...

  5. 利用分支限界法求解单源最短路(Dijkstra)问题

    分支限界法定义:采用Best fist search算法,并使用剪枝函数的算法称为分支界限法. 分支限界法解释:按Best first的原则,有选择的在其child中进行扩展,从而舍弃不含有最优解的分 ...

  6. 单源最短路——Bellman-Ford算法

    1.Dijkstra的局限性 Dijkstra算法是处理单源最短路径的有效算法,但它局限于边的权值非负的情况,若图中出现权值为负的边,Dijkstra算法就会失效,求出的最短路径就可能是错的. 列如以 ...

  7. 图论-单源最短路-SPFA算法

    有关概念: 最短路问题:若在图中的每一条边都有对应的权值,求从一点到另一点之间权值和最小的路径 SPFA算法的功能是求固定起点到图中其余各点的的最短路(单源最短路径) 约定:图中不存在负权环,用邻接表 ...

  8. [10.26_P2] 最短路 (单源最短路应用)

    单源最短路问题拓展 Description 给你一张图,图上有 n 个点,m 条边,要你找到两个点,使其最短路恰好包含给定的 k 个点.输出这条最短路的长度,输入保证有解. 输入格式 第一行两个数 n ...

  9. 【算法】单源最短路径和任意两点最短路径总结(补增:SPFA)

    [Bellman-Ford算法] [算法]Bellman-Ford算法(单源最短路径问题)(判断负圈) 结构: #define MAX_V 10000 #define MAX_E 50000 int ...

随机推荐

  1. Zen Coding in Visual Studio 2012

    http://www.johnpapa.net/zen-coding-in-visual-studio-2012 Zen Coding is a faster way to write HTML us ...

  2. 字符串查找KMP算法(转)

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  3. linux 下安装mysql

    看以下这篇文章就够了   http://www.cnblogs.com/xiaoluo501395377/archive/2013/04/07/3003278.html 查看有没有安装过:       ...

  4. mysql数据文件迁移到新的硬盘分区的方法

    该系统增加了一个硬盘.要创建新的分区/data文件夹,mysql对于数据文件夹/var/lib/mysql 1.  停止mysql维修 [root@localhost~]# service mysql ...

  5. c#基于这些,你已经看到了?(一)-----谁才刚刚开始学习使用

    1.注视(不要写的目光是流氓,从废话名盲人) '///'一般用于目光功能.凝视类. 2.热键 ctrl+k+d(有语法错误无法进行对齐) ctrl+j(高速弹出仅仅能提示) shift+end,shi ...

  6. 通过gradle运行测试脚本(转)

    练习一:HelloWorld 创建项目,源代码在src/main/java,测试源代码在src/test/java build.gradle的脚本: apply plugin: 'java' depe ...

  7. JAVA —— 文件输入输出

    import java.io.*; public class FileIO { public static void main(String[] args) { //1.相对路径 File testF ...

  8. js之第三方工具解析JSON

    1.JSON 仅仅是一种文本字符串.它被存储在 responseText 属性中 为了读取存储在 responseText 属性中的 JSON 数据,须要依据 JavaScript 的 eval 函数 ...

  9. 【web开发学习笔记】Structs2 Action学习笔记(两)

    action学习笔记2-大约action method讨论 Action运行的时候并不一定要运行execute方法,能够在配置文件里配置Action的时候用method=来指定运行哪个方法 也能够在u ...

  10. [ACM] poj 1088 滑雪 (内存搜索DFS)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 73409   Accepted: 27141 Description ...