本文主要是介绍最短路算法总结(dijkstra,flyod,bellmanford,spfa),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
总结
d i j k s t r a dijkstra dijkstra | h e a p − d i j k s t r a heap-dijkstra heap−dijkstra | b e l l m a n f o r d bellmanford bellmanford | s p f a spfa spfa | f l o y d floyd floyd | |
---|---|---|---|---|---|
最短路类型 | 单源 | 单源 | 单源 | 单源 | 全源 |
数据维护 | e [ u ] d [ u ] v i s [ u ] e[u] d[u] vis[u] e[u]d[u]vis[u] | e [ u ] d [ u ] v i s [ u ] e[u] d[u] vis[u] e[u]d[u]vis[u] 优先队列:距离优先 | e [ u ] d [ u e[u] d[u e[u]d[u] | e [ u ] d [ u ] v i s [ u ] e[u] d[u] vis[u] e[u]d[u]vis[u] 队列:时间优先 | d [ u ] d[u] d[u] |
算法 | 贪心 松弛 出圈 | 贪心 松弛 入队 出队 | 所有边松弛 | 出队点的出边松弛 | 动态规划(插点法) |
负边权 | 不能 | 不能 | 能 | 能 | 能 |
判负环 | 不能 | 不能 | 能 | 能 | 能 |
时间复杂度 | O ( n 2 ) O(n^2) O(n2) | O ( ( m + n ) l o g m O((m+n)logm O((m+n)logm) | O ( n m O(nm O(nm) | O ( k m n m ) O(km~nm) O(km nm) | O ( n 3 ) O(n^3) O(n3) |
下附代码实现
dijkstra
#include<iostream>
#include<vector>
using namespace std;
#define MAX_N 100000
#define inf 9999999
int n,m,s;
struct edge{int v,w;
};
vector<edge>e[MAX_N+5];
int d[MAX_N+5];
int vis[MAX_N+5];
void dijkstra()
{for(int i=0;i<=n;i++)d[i]=inf;d[s]=0;for(int i=1;i<n;i++){int u=0;for(int j=1;j<=n;j++)if(!vis[j]&&d[u]>d[j])u=j;vis[u]=1;for(auto ed:e[u]){int v=ed.v,w=ed.w;if(d[v]>d[u]+w)d[v]=d[u]+w;}}
}
int main()
{cin>>n>>m>>s;for(int i=1,a,b,c;i<=m;i++){scanf("%d %d %d",&a,&b,&c);e[a].push_back({b,c});}dijkstra();for(int i=1;i<=n;i++)cout<<d[i]<<" ";return 0;
}
heap_dijkstra
基于优先队列优化的dijkstra
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define MAX_N 100000
#define inf 0x7f7f7f7f
int n,m,s;
struct edge{int v,w;
};
vector<edge>e[MAX_N+5];
int d[MAX_N+5];
int vis[MAX_N+5];
priority_queue<pair<int,int>>p;
void dijkstra()
{p.push({0,s});for(int i=0;i<=n;i++)d[i]=inf;d[s]=0;while(p.size()){pair<int,int>t=p.top();p.pop();int u=t.second;if(vis[u])continue;vis[u]=1;for(auto ed:e[u]){int v=ed.v,w=ed.w;if(d[v]>d[u]+w){d[v]=d[u]+w;p.push({-d[v],v});}}}
}
int main()
{cin>>n>>m>>s;for(int i=1,a,b,c;i<=m;i++){scanf("%d %d %d",&a,&b,&c);e[a].push_back({b,c});}dijkstra();for(int i=1;i<=n;i++)cout<<d[i]<<" ";return 0;
}
floyd
#include<iostream>
#include<vector>
using namespace std;
#define MAX_N 100
#define inf 9999999
int n,m;
struct edge{int v,w;
};
int d[MAX_N+5][MAX_N+5];
int p[MAX_N+5][MAX_N+5];
void floyd()
{for(int k=1;k<=n;k++){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){if(d[i][j]>d[i][k]+d[k][j]){d[i][j]=d[i][k]+d[k][j];p[i][j]=k;} }}}return ;
}
void path(int i,int j)
{if(!p[i][j])return ;int k=p[i][j];path(i,k);printf("%d",k);path(k,j);return ;
}
int main()
{cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)d[i][j]=inf;d[i][i]=0;}for(int i=1,a,b,c;i<=m;i++){scanf("%d %d %d",&a,&b,&c);d[a][b]=c;}floyd();for(int i=1;i<=n;i++){for(int j=1;j<=n;j++)cout<<d[i][j]<<" ";cout<<endl;}int x,y;cin>>x>>y;cout<<x;path(x,y);cout<<y;return 0;
}
bellmanford
#include<iostream>
#include<vector>
using namespace std;
#define MAX_N 1000000
#define inf 0x7f7f7f7f
struct edge{int v,w;
};
vector<edge>e[MAX_N+5];
int d[MAX_N+5];
int n,m,s;
bool bellmanford()
{bool flag=0;for(int i=0;i<=n;i++)d[i]=inf;d[s]=0;for(int i=1;i<=n;i++){flag=0;for(int u=1;u<=n;u++){if(d[u]==inf)continue;for(auto ed:e[u]){int v=ed.v,w=ed.w;if(d[v]>d[u]+w){d[v]=d[u]+w;flag=1;}}}if(!flag)break;}return flag;
}
int main()
{cin>>n>>m>>s;for(int i=1,a,b,c;i<=m;i++){scanf("%d %d %d",&a,&b,&c);e[a].push_back({b,c});}cout<<bellmanford()<<endl;for(int i=1;i<=n;i++)cout<<d[i]<<" "; return 0;
}
spfa
基于队列优化的bellmanford
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define MAX_N 1000000
#define inf 0x7f7f7f7f
struct edge{int v,w;
};
vector<edge>e[MAX_N+5];
int d[MAX_N+5];
int vis[MAX_N+5];
int cnt[MAX_N+5];
int n,m,s;
queue<int>q;
bool spfa()
{bool flag=0;for(int i=0;i<=n;i++)d[i]=inf;d[s]=0;q.push(s);while(!q.empty()){int u=q.front();vis[u]=0;q.pop();for(auto ed:e[u]){int v=ed.v,w=ed.w;if(d[v]>d[u]+w){d[v]=d[u]+w;cnt[v]=cnt[u]+1;if(cnt[v]>=n)return 0;if(!vis[v])q.push(v),vis[v]=1;}}}return 1;
}
int main()
{cin>>n>>m>>s;for(int i=1,a,b,c;i<=m;i++){scanf("%d %d %d",&a,&b,&c);e[a].push_back({b,c});}cout<<bellmanford()<<endl;for(int i=1;i<=n;i++)cout<<d[i]<<" "; return 0;
}
这篇关于最短路算法总结(dijkstra,flyod,bellmanford,spfa)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!