最主要的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. Java新手入门的30个基本概念

    Java已经成为一个庞大而复杂的技术平台,对于开发者而言,特别是刚開始学习的人,要想更好的掌握Java技术,深入理解基本概念不可缺少,能够帮助你提高对Java的进一步了解.以下为你介绍了Java语言的 ...

  2. myEclipse项目部署按钮失效了,怎么办?

    myEclipse项目部署按钮失效了,按了以后没反应,怎么办? 步骤如下: 1.首先关闭MyEclipse. 2.然后删除Workspaces目录(存放您MyEclipse项目的地方)下的 " ...

  3. 基于android 社会的app短信分享 发送回调事件的实现

    摘要 前一段时间.由于项目的需要,采用ShareSDK该共享功能.其中包含 短信股吧.和呼叫系统,以分享要与成功处理服务器交互的消息后,(我不在乎在这里,收到.仅仅关心发出去了).可是ShareSDk ...

  4. Sqlserver 高并发和大数据存储方案

    Sqlserver 高并发和大数据存储方案 随着用户的日益递增,日活和峰值的暴涨,数据库处理性能面临着巨大的挑战.下面分享下对实际10万+峰值的平台的数据库优化方案.与大家一起讨论,互相学习提高!   ...

  5. Arcgis for Javascript之featureLayer图和属性互操作性

    说明:主要实现加载FeatureLayer并显示属性表,而要实现联动属性表与地图,首先,看看实施后的效果: 显示效果 如上图所看到的,本文章主要实现了下面几个功能:1.FeatureLayer属性表的 ...

  6. Android定调的发展

    首先,介绍一下Android系统支持的铃声格式. 有下面几种: 64赫兹Midi,AAC.AAC+.AMR.WAV.MP3.Real Audio.WMA.OGG等格式. 将音频文件设置成铃声非常eas ...

  7. Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质

    原文:Linux内核分析(六)----字符设备控制方法实现|揭秘系统调用本质 Linux内核分析(六) 昨天我们对字符设备进行了初步的了解,并且实现了简单的字符设备驱动,今天我们继续对字符设备的某些方 ...

  8. Arrays.asList的那点事

    import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List ...

  9. 关于Java和.NET之间的通信问题(JSON)

    前言: 最近项目在某XX领导的所谓指引下,非要转型Java,转就转吧,在转的过程前期是个痛苦期,特别.NET旧有项目和Java新项目需要通信时. 进入主题,Java和.NET之间需要通信,这时媒介很多 ...

  10. Linux了解进程的地址空间

    供Linux了解虚拟内存,非常好的引导了.原文链接:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26683523&i ...