基于算法导论图算法-单源最短路(第24章)
- 题目描述
- 问题分析
- 源代码
- 结果截图
题目描述
分别使用Dijkstra和Bellman-Ford算法实现最短路,输出最短路权值和路径
问题分析
源代码
void Dijkstra(Graph G, Vertex s);//不能用于负圈图
bool bellman_ford(Graph G, Vertex s);//可用于判断负圈
void print_shortest(Graph G, int s);//打印最短路
void print_shortest(Graph G, int s) {
printf("打印从顶点%d出发到所有顶点的最短路径(含权值):\n",s);
for (int i = 0; i < G->vexnum; i++) {
printf(" - %d : 权值(%d),路径为:", i,G->vertices[i].dist);
print_path_twoPoint(G, s, i);//打印两点路径
printf("\n");
}
}
void init_singleSource(Graph G, Vertex s) {
for (int i = 0; i < G->vexnum; i++) {
G->vertices[i].dist = INF;
G->vertices[i].pred = -1;
G->vertices[i].color = 0;//白色
}
G->vertices[s].dist = 0;
}
struct qnode {
int v;
int w;
qnode(int _v = -1,int _w = -1):v(_v),w(_w){}
bool operator<(const qnode& x)const {
return w > x.w;//这样优先队列建立小根堆
}
};
void Dijkstra(Graph G, Vertex s) {//不能用于负圈图
init_singleSource(G, s);
priority_queue<qnode> Q;
Q.push(qnode(s, 0));
qnode temp;
PtrToNode ptr;
while (!Q.empty()) {
temp = Q.top();
Q.pop();
int u = temp.v;
//下面两行是为了避免已经求出的最短路的顶点再次进行计算
if (G->vertices[u].color) continue;
G->vertices[u].color = 1;//黑色
for (ptr = G->vertices[u].adjto; ptr!=NULL; ptr = ptr->next) {
//relax松弛操作
if (!G->vertices[ptr->adjvex].color&&G->vertices[ptr->adjvex].dist > G->vertices[u].dist + ptr->weight) {
G->vertices[ptr->adjvex].dist = G->vertices[u].dist + ptr->weight;
G->vertices[ptr->adjvex].pred = u;
Q.push(qnode(ptr->adjvex, G->vertices[ptr->adjvex].dist));
}
}
}
}
bool bellman_ford(Graph G, Vertex s) {//可用于判断负圈
PtrToNode ptr;
init_singleSource(G, s);
for (int i = 0; i < G->vexnum - 1; i++) {//对所有边松弛n-1次,如果还可以松弛,证明图有负环
for (int j = 0; j < G->vexnum; j++) {
for (ptr = G->vertices[j].adjto; ptr != NULL; ptr = ptr->next) {
//松弛操作
if (G->vertices[ptr->adjvex].dist > G->vertices[j].dist + ptr->weight) {
G->vertices[ptr->adjvex].dist = G->vertices[j].dist + ptr->weight;
G->vertices[ptr->adjvex].pred = j;
}
}
}
}
for (int j = 0; j < G->vexnum; j++) {//检测看是否图有负环
for (ptr = G->vertices[j].adjto; ptr != NULL; ptr = ptr->next) {
if (G->vertices[ptr->adjvex].dist > G->vertices[j].dist + ptr->weight) {
return false;
}
}
}
return true;
}
int main() {
//有向图的随机生成([图论(一)图的建立](http://blog.csdn.net/deep_kang/article/details/70877468))
CreateRandomDirectGraph();
Graph G = CreateDirectGraph();
printf("打印图结构:\n");
print_EdgeWeight(G);
/*printf("\n下面是bfs:\n");
BFS(G, 0);*/
/*printf("\n下面是dfs:\n");
DFS(G);*/
//测试单源最短路
cout << "测试单源最短路" << endl;
if (bellman_ford(G, 0)) {
print_shortest(G, 0);
Dijkstra(G, 0);
print_shortest(G, 0);
}
else {
printf("图有负环\n");
}
return 0;
}
结果截图