1.使用场景,迪杰斯特拉: 一个点到其他各个点的最短路径。弗洛伊德:从i到j的最短路径。
在实现上,Dijstra需要两个数组记录当前已有的最短路径和地点是否已经加入到了集合当中,贪心思想。弗洛伊德为三层for,算法复杂度分别是n方和n的三次方。
2.Dijkstra:
cpp
#include <bits/stdc++.h>
using namespace std;
const int inf=0x7fffffff;
int n,e,s;
int dis[101],check[101];//dis最短路径 是否加入到了集合中
int graph[101][101];//路径长度
int main(){
for(int i=1;i<=100;i++){
dis[i]=inf;//初始为无穷大
}
cin>>n>>e;//地点的数量和道路的数量
for(int i=1;i<=e;i++){
int a,b,c;//从a到b的长度是c
cin>>a>>b>>c;
graph[a][b]=c;
}
cin>>s;
dis[s]=0;//那个作为起点
//在dis找到尚未加入到集合中的最短的点 将之加入到集合中
for(int i=1;i<=n;i++){
int minv=inf,minx;
for(int j=1;j<=n;j++){
if(dis[j]<=minv&&!check[j]){
minv=dis[j];
minx=j;
}
}
check[minx]=true;
//拿着这个点去更新其他的位置
for(int j=1;j<=n;j++){
if(graph[minx][j]>0){//可达
if(dis[minx]+graph[minx][j]<dis[j]){
dis[j]=dis[minx]+graph[minx][j];//距离更新
}
}
}
}
for(int i=1;i<=n;i++){
cout<<dis[i]<<" ";
}
return 0;
}
在实际使用的时候,经常需要记录路径。只需要在这个基础上增加一个pre数组来记录他的前一个节点。
Floyed:
cpp
//弗洛伊德算法
void Floyd(AMGraph* G) {
int distance[MVNum][MVNum];
int i, j, k;
//初始化距离矩阵
for (i = 0; i < G->vexnum; i++) {
for (j = 0; j < G->vexnum; j++) {
distance[i][j] = G->arcs[i][j];
}
}
//中间节点迭代
for (k = 0; k < G->vexnum; k++) {
for (i = 0; i < G->vexnum; i++) {
for (j = 0; j < G->vexnum; j++) {
if (distance[i][k] + distance[k][j] < distance[i][j]) {
distance[i][j] = distance[i][k] + distance[k][j];
}
}
}
}
//输出
printf("每对顶点间的最短距离:\n");
for (i = 0; i < G->vexnum; i++) {
for (j = 0; j < G->vexnum; j++) {
if (distance[i][j] == MaxInt) {
printf("∞ ");
}
else {
printf("%d ", distance[i][j]);
}
}
printf("\n");
}
}
---没有比刷题更好的理解方式---