有如下有向图:
要求计算源点a到目的点k的最短距离。
运行结果:
可以使用 分支限界法
解决。
代码如下:
#include <iostream>
#define MAX_V 100
using namespace std;
class Node{
public:
int index; //顶点编号
int dist; //到源点的长度
Node* next; //链表的下一个节点
Node(int index = 0):index(index){
this->dist = 0xFFFFFFF;
this->next = 0;
}
};
/*优先队列*/
class List{
public:
Node* head;
List(){
head = new Node();
}
~List(){
delete head;
}
void add(Node* node){
for(Node* i = head; i != 0; i = i->next){
if(i->next == 0 || node->dist < i->next->dist){
node->next = i->next;
i->next = node;
break;
}
}
}
Node* removeFirst(){
if(!empty()){
Node* temp = head->next;
head->next = head->next->next;
return temp;
}
return 0;
}
bool exists(Node* node){
for(Node* i = head->next; i != 0; i = i->next){
if(i == node){
return true;
}
}
return false;
}
bool empty(){
return head->next == 0;
}
};
/* 单源最短路径-使用分支限界法
* map : 有向图邻接矩阵
* n : 顶点个数
* s : 源点下标
* d : 目的点下标
* 返回值: 源点到目的点的最知路长度
* */
int Dijkstra(int map[MAX_V][MAX_V], int n, int s, int d){
//初始化结构
List opened;
List closed;
Node** nodes = new Node*[n];
for(int i = 0; i < n; i++){
nodes[i] = new Node(i);
}
nodes[s]->dist = 0;
//算法开始
opened.add(nodes[s]);
while(!opened.empty()){
Node* temp = opened.removeFirst();
//遍历所有相邻顶点
for(int i = 0; i < n; i++){
if(map[temp->index][i] != 0 && !closed.exists(nodes[i])){ 剪枝
int distance = temp->dist + map[temp->index][i];
if(distance < nodes[i]->dist){ ///如果到源点有更小的距离,则更新这个距离
nodes[i]->dist = distance;
}
//添加相邻顶点到开放队列中
if(!opened.exists(nodes[i])){
opened.add(nodes[i]);
}
}
}
closed.add(temp);
}
return nodes[d]->dist;
}
int main(){
int map[MAX_V][MAX_V] = {0}; // 0 认为不可达
map[0][1] = 2;
map[0][2] = 3;
map[0][3] = 4;
map[1][2] = 3;
map[1][5] = 2;
map[1][4] = 7;
map[2][6] = 2;
map[2][5] = 9;
map[3][6] = 2;
map[4][7] = 10;
map[4][8] = 10;
map[5][6] = 1;
map[5][8] = 3;
map[6][8] = 5;
map[6][9] = 1;
map[7][10] = 10;
map[8][10] = 10;
map[9][8] = 2;
map[9][10] = 2;
cout << "min distance:" << Dijkstra(map, 11, 0, 10);
return 0;
}