最短路径
总结:
DIJ算法 :
》可以求一个源点到其他各个点的最短路径
》需要两个一维数组,一个记录当前的最短路径值,另一个记录已经求出最短路径的节点
》每次都是从当前路径的最短路径值中寻找最小的,进行更新最短路径。
Floyed算法:
》可以求出每两个节点间的最短路径。
》需要一个二维数组,记录最短路径值
》枚举两个节点之间所有可能的路径,进行最短更新。
SPFA算法:
》可以求出一个源点到另一个点的最短路径。可以判断邻接表是否存在有向环
》需要一个栈或队列,三个一维数组,一个记录当前栈中存在元素,一个记录最短路径值,一个记录对每个节点的操作 次数(当对节点的操作次数大于节点总数时,邻接表存在有向环)
》从源点开始,将源点出栈,对与其相邻的点,进行最短优化,可以优化,则将其入栈,该点操作次数+1。
DIJ 算法:
将N的顶点分成两组:
第一组: S已经出最短路径的终点的集合。
第二组: V还没有求出最短路径的集合。
将各个顶点与起始点S0间的最短路径长度递增的次序,逐个将V数组的顶点加入到S数组中。过程中保证从S0到集合S中各顶点路径长度最短。
Floyed 算法:
D[i][j]表示Vi, Vj之间的最短路径。给Vi,Vj之间加上顶点V0.
比较D[i][j] 与 D[i][V0]+D[V0][j]的大小,更新D[i][j]就Ok
DIJ算法:时间复杂度O(n^2) 值计算出以s为起点的所有路径的最短距离
void DJS(){ int i, j; for(i=0; i<n; i++) //初始化记录距离的数组d { v[i]=false; d[i]=map[s][i]; if(d[i] < max) path[i]=s; //当前终点i到起点有弧将i指向s else path[i]=i; //无弧指向本身 } v[s]=true; //标记开始点 for(i=1; i<n; i++) //对其余的n-1个点,进行循环 { int min=max, t; for(j=0; j<n; j++) //选择当前已走路径中d最小的,终点记为t if(!v[j] && d[j]<min) { t=j; min=d[j]; } v[t]=true; //将t标记 for(j=0; j<n; j++) //更新从t出发到达未标记点的最短路径长度 if(!v[j] && d[t]+map[t][j]<d[j]) { d[j]=d[t]+map[t][j]; path[j]=t; //当前距离更新则更新路径 } } }
Floyed算法:时间复杂度 O(n^3) 将所有的点间的最短距离都算出来了
void Floyed() { int i, j, k; for(i=0; i<n; i++) for(j=0; j<n; j++) { d[i][j]=map[i][j]; //初始化D数组 if(d[i][j] < max) path[i][j]=i; //i,j之间有弧就将i记为j的前驱 else path[i][j]=j; } for(k=0; k<n; k++) //代表i, j之间连接路径的顶点 for(i=0; i<n; i++) for(j=0; j<n; j++) if(d[i][k]+d[k][j] < d[i][j]) { d[i][j]=d[i][k]+d[k][j]; path[i][j]=path[k][j]; } }
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1428
http://acm.hdu.edu.cn/showproblem.php?pid=1142
http://acm.hdu.edu.cn/showproblem.php?pid=3790 增加难度,多了一个优先级别,距离级别1,花费级别2

浙公网安备 33010602011771号