数据结构之最短路径的 Dijkstra Algorithm && Floyd Algorithm
来源:互联网 发布:苏州远洋数据 编辑:程序博客网 时间:2024/05/16 01:07
没有什么说的。代码中讲解的应该还算明确。
但是我想说的是一定要把最短路径和最小生成树给分开。。最小生成树是求一个Graph(这个图中必定是全部联通图)中,求解所有子树中所有路径之和最小的子树。。而最短路径则求Graph中是从一个点到另一个点路径之和最短的路径。这完全是两个问题。。没有任何联系!
#include <iostream>#include <cstdio>#include <string>#include <cmath>#include <algorithm>#include <cstring>#include <map>#include <queue>#include <stack>#define INF 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a));#define For(a,b) for(int i = a;i<b;i++)#define LL long long#define MAX_N 100010#define VN 10using namespace std;typedef int Vextype;typedef int Adjtype;typedef int Elemtype;typedef struct{ Vextype vexs[VN]; Adjtype arcs[VN][VN];}Graph; //邻接矩阵的存储结构typedef struct{ Adjtype length; int prevex;}Path;//Dijkstra算法中的操作对象typedef struct{ Adjtype weight[VN][VN]; int nextVex[VN][VN];}ShortPath;//Floyd算法中的操作对象Elemtype Dijk_flag = 1;//判断该点是否到所有点都有通路的标志Elemtype mark[VN][VN];//记录原始邻接矩阵的数据元素/* 初始化Dijkstra algorithm中的dis数组。 其实也就是将0到Graph中所有的点的距离 以及所有点的前驱(0),置于dis数组 如果说没有通路。则置为-1。*/void init(Graph * graph,Path dis[],Elemtype node_num){ dis[0].length = 0; dis[0].prevex = 0; graph->arcs[0][0] = 1; for(int i = 1; i<node_num; i++) { dis[i].length = graph->arcs[0][i]; if(dis[i].length != MAX_N) { dis[i].prevex = 0; } else dis[i].prevex = -1; }}void Dijkstra(Graph * pgraph,Path dis[],Elemtype node_num){ init(pgraph,dis,node_num); int minw,minVex; /* 这个for循环每循环一次找到一个 距离初始点的最短距离的点 */ for(int i = 1; i<node_num; i++) { minw = MAX_N; minVex = 0; /* 该for循环是为了找到当前dis数组中最小的length值 */ for(int j = 1; j<node_num; j++) { if(pgraph->arcs[j][j] == 0 && dis[j].length < minw) { minw = dis[j].length; minVex = j; } } /* 此判断是该Graph是否所有的点可以连成一个通路 如果不能·则用全局变量Dijk_flag标记 */ if(minVex == 0) { Dijk_flag = 0; break; } pgraph->arcs[minVex][minVex] = 1; /* 更新dis数组中剩下的元素中的前驱和length值 */ for(int j = 1; j<node_num; j++) { if(pgraph->arcs[j][j] == 0 && dis[j].length > dis[minVex].length + pgraph->arcs[minVex][j]) { dis[j].length = dis[minVex].length + pgraph->arcs[minVex][j]; dis[j].prevex = minVex; } } }}void Floyd(Graph *pgraph,ShortPath *ppath,Elemtype node_num){ /* 初始化ppath结构体中的数组元素。 如果从i点到j点有通路,则nextVex[i][j] = j; 否则等于-1。 不论是否有通路,都将weight值赋予weight[i][j]. */ for(int i = 0; i<node_num; i++) { for(int j = 0; j<node_num; j++) { if(pgraph->arcs[i][j] != MAX_N) { ppath->nextVex[i][j] = j; } else ppath->nextVex[i][j] = -1; ppath->weight[i][j] = pgraph->arcs[i][j]; } } /* 每次外层循环k不变,就相当于喜欢是每次将k点插入i到j的路径当中去。 这样遍历一遍求最短Graph中可以连通的点中。每两个点之间的最短路径。 */ for(int k = 0; k<node_num; k++) for(int i = 0; i<node_num; i++) for(int j = 0 ; j<node_num; j++){ if(ppath->weight[i][k] >= MAX_N || ppath->weight[k][j] >= MAX_N) continue; if(ppath->weight[i][j] > ppath->weight[i][k] + ppath->weight[k][j]) { ppath->weight[i][j] = ppath->weight[i][k] + ppath->weight[k][j]; ppath->nextVex[i][j] = ppath->nextVex[i][k]; } }}int main(){ Graph pgraph; Path dis[VN]; ShortPath shpath; int node_num = 6; int edge_num = 11; for(int i = 0; i<node_num; i++) { for(int j = 0; j<node_num; j++){ if(i==j) mark[i][j] = 0; else mark[i][j] = MAX_N; } } int node_start,node_stop,edge_val = 0; for(int i = 0; i<edge_num; i++) { cin>>node_start>>node_stop>>edge_val; mark[node_start][node_stop] = edge_val; } /* 为arcs邻接矩阵数组赋初值 */ for(int i = 0; i<node_num; i++) { for(int j = 0; j<node_num; j++) { pgraph.arcs[i][j] = mark[i][j]; } } Dijkstra(&pgraph,dis,node_num); if(Dijk_flag) { cout<<"该图中所有的结点连通,且这是一个连通图。"<<endl<<endl; } else cout<<"这个图中存在不可访问到的结点,所以这不是一个连通图。"<<endl<<endl; cout<<"1 — 0的最短路径长度是: "<<endl<<dis[1].length<<endl<<endl; cout<<"1 — 0的最短路径是:"<<endl; cout<<"V_1 -> "; int prev = 1; while(1) { prev = dis[prev].prevex; cout<<"V_"<<prev<<" -> "; if(prev == 0) { cout<<endl<<endl; break; } } /* 由于经过Dijkstra算法的调用,arcs数组中一些元素已被改变。 所以需要再次对arcs数组进行初始化。 */ for(int i = 0; i<node_num; i++) { for(int j = 0; j<node_num; j++) { pgraph.arcs[i][j] = mark[i][j]; } } Floyd(&pgraph,&shpath,node_num); cout<<"0 — 1的最短路径长度是: "<<endl<<shpath.weight[0][1]<<endl<<endl; cout<<"0 — 1的最短路径是:"<<endl; cout<<"V_0 -> "; int next = shpath.nextVex[0][1]; while(1) { cout<<"V_"<<next<<" -> "; next = shpath.nextVex[next][1]; if(next == 1) { cout<<"V_1"<<endl<<endl; break; } } //system("pause"); return 0;}/*2016.10.7测试样例:0 1 500 2 100 4 451 2 151 4 52 0 202 3 153 1 203 4 354 3 305 3 3*/
0 0
- 数据结构之最短路径的 Dijkstra Algorithm && Floyd Algorithm
- 最短路径之迪科斯彻算法(Dijkstra's algorithm)的java实现
- 【Python排序搜索基本算法】之Dijkstra最短路径算法(Dijkstra's Shortest-Path Algorithm)
- 最短路径之djikstra algorithm
- GeeksForGeeks-Dijkstra’s shortest path algorithm最短路径
- 最短路径之Dijkstra+Floyd算法
- 最短路径之Dijkstra+Floyd算法
- Geeks面试题:Floyd Warshall Algorithm 所有顶点之间的最短路径问题
- 最短路径&&Dijkstra&&Floyd
- 数据结构之最短路径(Floyd)
- 数据结构之最短路径(Floyd)
- 数据结构基础6.4:最短路径(Dijkstra, Floyd)
- 数据结构-最短路径—Dijkstra算法和Floyd算法
- 数据结构之最短路径(DijKstra)
- 最短路径之Dijkstra算法与Floyd 算法
- 最短路径之Dijkstra算法和Floyd-Warshall算法
- 最短路径算法(Shortest Paths Algorithm)
- Geeks : Dijkstra’s Algorithm for Adjacency List Representation 最短路径
- 使用VS2012编译项目报错如下:
- Leetcode 02 Add Two Numbers
- 关于那些年轻的岁月
- React-native导入三方库的报错
- Three-axis-acceleration-sensor Linux driver
- 数据结构之最短路径的 Dijkstra Algorithm && Floyd Algorithm
- Linux下加载.ko驱动模块的两种方法:insmod与modprobe
- Qt学习之路(5):组件布局
- windows获取控制台窗口的句柄
- ZigBee协议
- 线程安全的单例模式的几种实现方法分享
- ant工具简介
- 学习笔记_多进程
- [ 备战NOIP2016 ] 字符串匹配 - 哈希