最短路算法

来源:互联网 发布:遗传算法的基本思想 编辑:程序博客网 时间:2024/05/20 04:27

最短路

最短路算法有很多,具体哪个好,和数据是有很大关系的

Bellman-Ford

从起点开始向外扩展,最坏O(|V|*|E|),实际体验比O(|E|log|V|) 的Dijkstra可能快

#include<stdio.h>#include<algorithm>#define MAX_E 4002#define MAX_V 1002#define INF 0x3f3f3fusing namespace std;struct edge{int from,to,cost;};edge es[MAX_E];int d[MAX_V],V,E;void bellman_ford(int s){    fill(d,d+V+1,INF);    d[s]=0;    while(true){        bool update=false;        for(int i=0;i<E;i++){            edge e=es[i];            if(d[e.from]!=INF&&d[e.from]+e.cost<d[e.to]){                d[e.to]=d[e.from]+e.cost;                update=true;            }        }        if(!update) break;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

spfa

将上面的算法用堆优化后就是spfa了,该算法是不稳定的,但大部分情况下该算法是最快的

#include<stdio.h>#include<queue>#include<algorithm>#define MAX_E 4002#define MAX_V 1002#define INF 0x3f3f3fusing namespace std;struct edge{int from,to,cost;};edge es[MAX_E];int d[MAX_V],V,E;void bellman_ford(int s){    fill(d,d+V+1,INF);    d[s]=0;    queue<int> que;    que.push(s);    while(!que.empty()){        int t=que.front();que.pop();        edge e=es[t];        if(d[e.from]+e.cost<d[e.to]){            d[e.to]=d[e.from]+e.cost;            que.push(e.to);        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Dijkstra

和上面两个算法的原理差不多,只是使用了优先队列实现,以减少冗余操作,复杂度O(|E|log|V|)

#include<stdio.h>#include<queue>#include<vector>#define INF 0x3f3f3f#define MAX_N 1002using namespace std;struct edge{int to,cost;}E;typedef pair<int ,int> P;//f 距离 s 顶点int V,T;int d[MAX_N];bool operator <(P x,P y){    return x.first>y.first;}void dijkstra(int s,vector<edge> *G){    //vector<edge> G[V+1];    priority_queue<P> que;    fill(d,d+V+1,INF);    d[s]=0;    que.push(P(0,s));    while(!que.empty()){        P p=que.top();que.pop();        int v=p.second;        if(d[v]<p.first) continue;        for(int i=0;i<G[v].size();i++){            edge e=G[v][i];            if(d[v]+e.cost<d[e.to]){                d[e.to]=d[v]+e.cost;                que.push(P(d[e.to],e.to));            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

补充

次短路算法

#include<cstdio>#include<queue>#include<vector>#include<algorithm>#define INF 0x3f3f3f3f#define MAX_N 1005using namespace std;struct edge{int to,cost;};typedef pair<int,int> P;int dist[MAX_N];    //最短路int dist2[MAX_N];   //次短路int N;vector<edge> G[MAX_N];void solve(){    priority_queue<P,vector<P>,greater<P> > que;    fill(dist,dist+N,INF);    fill(dist2,dist2+N,INF);    dist[0]=0;    que.push(P(0,0));    while(!que.empty()){        P p=que.top();que.pop();        int v=p.second,d=p.first;        if(d>dist2[v]) continue;        for(int i=0;i<G[v].size();i++){            edge &e=G[v][i];            int d2=d+e.cost;            if(d2<dist[e.to]){                swap(dist[e.to],d2);                que.push(P(dist[e.to],e.to));            }            if(dist2[e.to]>d2&&dist[e.to]<=d2){                dist2[e.to]=d2;                que.push(P(dist2[e.to],e.to));            }        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

也可以用次短路与最短路比较,判断最短路是否唯一


原创粉丝点击