最主要的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 快速编写HTML/CSS代码的实现

    在本文中我们将展示一种新的使用仿CSS选择器的语法来快速开发HTML和CSS的方法.它由Sergey Chikuyonok开发. 你在写HTML代码(包括所有标签.属性.引用.大括号等)上花费多少时间 ...

  2. Bombing HDU, 4022(QQ糖的消法)

    Bombing From:HDU, 4022 Submit Time Limit: 4000/2000 MS (Java/Others)      Memory Limit: 65768/65768 ...

  3. 使用 svn+maven+jenkins(hudson)+Publish Over SSH plugins 构建持续集成及自动远程发布体系(转)

    1.安装jenkins 2.浏览器访问jenkins主页 http://192.168.0.1:8080/,点击“系统管理” 3.在插件管理中,安装Publish Over SSH插件 4.在系统设置 ...

  4. Oracle中merge into的使用 (转)

    该命令使用一条语句从一个或者多个数据源中完成对表的更新和插入数据. ORACLE 9i 中,使用此命令必须同时指定UPDATE 和INSERT 关键词,ORACLE 10g 做了如下改动. 1.ins ...

  5. gdb经常使用的命令

    在调试程序的时候,gdb是一柄利器,恰当的使用gdb能够解决掉程序的很多bug. gdb并不检查语法错误.那是gcc或者g++的事情,gdb干的是调试的事情. 说明: (1)gdb 程序名 [core ...

  6. [Android] App在三星某些机子上闪退:"不保留活动"

    今天遇到用户反映应用总是闪退. 现象:在MainActivity后,只要进入任何主进程相关的二级界面,都会导致应用闪退(注:不是崩溃引起的,只是闪退) 分析:1.看log日志,退出前有抛出异常,但查看 ...

  7. C#使用xpath找到一个节点

    Xpath这是非常强大.但对比是一个更复杂的技术,希望上面去博客园特别想看看一些专业职位.下面是一些简单Xpath的语法和示例,给你参考 <?xml version="1.0" ...

  8. 微通道产品经理Grover采访:美国的微通道设计

    "'哥'在中国是一种尊称吗?哈哈.我们平时都叫张小龙'龙哥'." "是的.Dan哥,当你认为某个人牛逼的时候,你就能够叫他'哥'." 我对于Dan Grover ...

  9. MOCK.JS 生成随机数据,拦截 Ajax 请求

    mock.js 的用处 前后端分离 :让前端攻城师独立于后端进行开发. 增加单元测试的真实性 :通过随机数据,模拟各种场景. 开发无侵入 :不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响 ...

  10. Apriori算法Python实现

    Apriori如果数据挖掘算法的头发模式挖掘鼻祖,从60年代开始流行,该算法非常简单朴素的思维.首先挖掘长度1频繁模式,然后k=2 这些频繁模式的长度合并k频繁模式.计算它们的频繁的数目,并确保其充分 ...