最短路徑四種解法
阿新 • • 發佈:2021-01-12
最短路徑四種解法
最短路徑的四種解法
在學習“圖”的時候,遇到過一道經典的題:最短路徑。最短路徑有四種最經典的解法。廢話不多說,直接上程式碼。
弗洛伊德演算法
//Floyd-Warshall #include<iostream> using namespace std; const int M=999999; int n,m,p1,p2,l; int map[1000][1000]; int main() {<!-- --> cin>>n>>m; for (int i=1;i<=n;i++) {<!-- --> for (int j=1;j<=n;j++) {<!-- --> if (i==j) {<!-- --> map[i][j]=0; } else {<!-- --> map[i][j]=M; } } } for (int i=1;i<=m;i++) {<!-- --> cin>>p1>>p2>>l; map[p1][p2]=l; } for (int k = 1; k <= n; k++) {<!-- --> for (int i = 1; i <= n; i++) {<!-- --> for (int j = 1; j <= n; j++) {<!-- --> if (map[i][j] > map[i][k] + map[k][j]) {<!-- --> map[i][j] = map[i][k] + map[k][j]; } } } } for (int i=1;i<=n;i++) {<!-- --> for (int j=1;j<=n;j++) {<!-- --> cout<<map[i][j]; } cout<<endl; } return 0; }
弗洛伊德演算法的時間複雜度O(n³),多源、無負權邊,時效性較差。
迪傑斯特拉
//Dijkstra #include <iostream> using namespace std; const int M=99999999; int n,m,p1,p2,l,map[100][100],dis[1000],book[1000]={<!-- -->0},mi,u; int main() {<!-- --> cin>>n>>m; for (int i=1;i<=n;i++) {<!-- --> for (int j=1;j<=n;j++) {<!-- --> if (i==j) {<!-- --> map[i][j]=0; } else {<!-- --> map[i][j]=M; } } } for (int i=1;i<=m;i++) {<!-- --> cin>>p1>>p2>>l; map[p1][p2]=l; } book[1]=1; for (int i=1;i<=n;i++) {<!-- --> dis[i]=map[1][i]; } for (int i=1;i<=n-1;i++) {<!-- --> mi=M; for (int j=1;j<=n;j++) {<!-- --> if (dis[j]<mi&&book[j]==0) {<!-- --> mi=dis[j]; u=j; } } book[u]=1; for (int k=1;k<=n;k++) {<!-- --> if(map[u][k]<M) {<!-- --> if (dis[k]>dis[u]+map[u][k]) {<!-- --> dis[k]=dis[u]+map[u][k]; } } } } for (int i=1;i<=n;i++) {<!-- --> cout<<dis[i]<<" "; } return 0; }
迪傑斯特拉的時間複雜度O(n²),單源、無負權,時效性較好。
貝爾曼·福特
//Bellman-Ford #include <iostream> using namespace std; const int M=9999999; int main() {<!-- --> int n,m; cin>>n>>m; int p1[100],p2[100],l[100]; int dis[1000]; for (int i=1;i<=m;i++) {<!-- --> cin>>p1[i]>>p2[i]>>l[i]; } for (int i=1;i<=n;i++) {<!-- --> dis[i]=M; } dis[1]=0; for (int i=1;i<=n-1;i++) {<!-- --> for (int j=1;j<=m;j++) {<!-- --> if (dis[p2[i]]>dis[p1[i]]+l[i]) {<!-- --> dis[p2[i]]=dis[p1[i]]+l[i]; } } } for (int i=1;i<=n;i++) {<!-- --> cout<<dis[i]<<" "; } return 0; }
貝爾曼·福特的時間複雜度O(n²),單源、可以判斷是否為負權,時效性較好。
SPFA-貝爾曼·福特佇列優化
//SPFA
#include <iostream>
using namespace std;
const int inf=9999999;
int main()
{<!-- -->
int n,m;
cin>>n>>m;
int p1[1000],p2[1000],l[1000];
int dis[1000];
int book[1000];
int first[1000];
int next[1000];
int que[1000]={<!-- -->0};
int tail=1,head=1;
int k;
for (int i=1;i<=n;i++)
{<!-- -->
dis[i]=inf;
}
dis[1]=0;
for (int i=1;i<=n;i++)
{<!-- -->
book[i]=0;
}
for (int i=1;i<=n;i++)
{<!-- -->
first[i]=-1;
}
int i;
for (i=1;i<=m;i++)
{<!-- -->
cin>>p1[i]>>p2[i]>>l[i];
next[i]=first[p1[i]];
first[p1[i]]=i;
}
que[tail]=1;
tail++;
book[i]=1;
while (head<tail)
{<!-- -->
k=first[que[head]];
while(k!=1)
{<!-- -->
if (dis[p2[k]]>dis[p1[k]]+l[k])
{<!-- -->
dis[p2[k]]=dis[p1[k]]+l[k];
}
if (book[p2[k]]==0)
{<!-- -->
que[tail]=p2[k];
tail++;
book[p2[k]]=1;
}
}
k=next[k];
head++;
}
for (i=1;i<=n;i++)
{<!-- -->
cout<<dis[i]<<" ";
}
return 0;
}
貝爾曼·福特佇列優化的時間複雜度最大為O(nm),最小為O(n),單源、可以判斷是否為負權,時效性相對好。 本文結束了,點個贊再走唄o( ̄▽ ̄)ブ</em>