hdu1874(最短路:一道题学习Floyd,Dijkstra,Bellman-Ford,SPFA)

Floyd,Dijkstra,Bellman-Ford,SPFA的比较

http://blog.csdn.net/xiazdong/article/details/8193680

Floyd(动态规划)

1,从任意一条单边路径开始。所有两点之间的距离是边的权,

      如果两点之间没有边相连,则权为无穷大。

2,对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比已知的路径更短,

      如果是更新它。

#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>

#define MAXN 1005
#define MAX 205
#define INF 0xfffffff

using namespace std;

//struct Path{int u,v,w;}path[MAXN];
int mp[MAX][MAX];
int s,e,n,m;
int u,v,w;
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
            //Floyd算法
            for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(i!=j)mp[i][j]=INF;
            for(int i=0;i<m;i++){
                    scanf("%d%d%d",&u,&v,&w);
                    if(mp[u][v]>w) mp[u][v]=mp[v][u]=w;
            }
            scanf("%d%d",&s,&e);
            for(int k=0;k<n;k++)
                for(int i=0;i<n;i++)
                    for(int j=0;j<n;j++){
                            int t=mp[i][k]+mp[k][j];
                            if(mp[i][j]>t) mp[i][j]=t;
                    }
            if(mp[s][e]<INF) printf("%d\n",mp[s][e]);
            else printf("-1\n");
    }//while
    return 0;
}

Dijkstra(贪心)

1,初始时令 起点s加入集合A,其余顶点组成集合B,

      B中顶点对应的距离值若存在<s,bi>,dis(bi)>为其权值,若不存在dis(bi)为∞

2.,从B中选取一个与A中顶点有关联边且权值最小的顶点t,加入到S中

3.,对其余A中顶点的距离值进行修改:若加进t作中间顶点,从as到ai的距离值缩短,

       则修改此距离值重复上述步骤2、3,直到A中包含所有顶点

#include <cstdio>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <queue>

#define MAXN 1005
#define MAX 205
#define INF 0xfffffff

using namespace std;

//struct Path{int u,v,w;}path[MAXN];
int mp[MAX][MAX];
int s,e,n,m;
int u,v,w;
int dis[MAX],vis[MAX];
void Dijkstra(){
    int i,j,k,mi;
    memset(vis,0,sizeof(vis));
    for(i=0;i<n;i++) dis[i]=mp[s][i];
    dis[s]=0;
    for(i=0;i<n;i++){
        mi=INF;
        for(j=0;j<n;j++){
            if(!vis[j]&&dis[j]<mi){
                mi=dis[j];
                k=j;
            }//if
        }//for_j
        if(mi==INF) break;
        vis[k]=1;
        for(j=0;j<n;j++)
            if(!vis[j]&&dis[j]>dis[k]+mp[k][j])
                dis[j]=dis[k]+mp[k][j];
    }
    if(dis[e]<INF) printf("%d\n",dis[e]);
    else printf("-1\n");
}

int main(){
            while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=0;i<n;i++) for(int j=0;j<n;j++) mp[i][j]=INF;
            for(int i=0;i<m;i++){
                    scanf("%d%d%d",&u,&v,&w);
                    if(mp[u][v]>w) mp[u][v]=mp[v][u]=w;
            }
            scanf("%d%d",&s,&e);
            Dijkstra();

    }//while
    return 0;
}

Bellman-Ford

1,初始化:将除源点外的所有顶点的最短距离值 d[i]置为∞, d[s]=0;

2,迭代求解:对每条边 ,dist[Vi] + (Vi,Vj)和dist[Vj],并将小的赋给dist[Vj]

(重复以上操作n − 1次)

3,检验负权回路(本题略)再重复操作一次,如dist[Vj] > dist[Vi] + (Vi,Vj),则此图存在负权环

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>

#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 205
#define MAXM 2005
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)

using namespace std;

int n,m,s,e;
struct Path{
    int  u,v,w;
}p[MAXM];
int dis[MAXN];

void Bellman_Ford(){
    int i,j;
    for(i=0;i<n;i++)  dis[i] = INF;
    dis[s]=0;
    for(i=0;i<n;i++)
        for(j=0;j<2*m;j++)
            dis[p[j].u]=min(dis[p[j].u],dis[p[j].v]+p[j].w);
    if(dis[e]<INF) printf("%d\n",dis[e]);
    else printf("-1\n");
}
int main(){
    int u,v,w;
    int i,j; 
    while(scanf("%d%d",&n,&m)!=EOF){
        s=1;e=n;
        int num=0;
        //for(i=0;i<=n;i++) for(j=0;j<=n;j++) mp[i][j]=INF;
        for(i=0;i<m;i++){
            scanf("%d%d%d",&u,&v,&w);
                p[num].u=u;
                p[num].v=v;
                p[num++].w=w;
                p[num].u=v;
                p[num].v=u;
                p[num++].w=w;
        }
        scanf("%d%d",&s,&e);
        Bellman_Ford();
    }
    return 0;
}

SPFA———bfs方法

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <set>
using namespace std;

#define INF 999999999
int mp[210][210],flag[210],d[210];
int m,n,s,e;
void SPFA(){
    int i,x;
    queue<int>q;
    memset(flag,0,sizeof(flag));
    for(i=0;i<n;i++) d[i]=INF;
    d[s]=0;
    q.push(s);
    while(!q.empty()){
        x=q.front();
        q.pop();
        flag[x]=0;
        for(i=0;i<n;i++){
            if(d[i]>d[x]+mp[x][i]){
                d[i]=d[x]+mp[x][i];
                if(!flag[i]){q.push(i);flag[i]=1;}
            }//if
        }//for
    }//while
    printf("%d\n",d[e]<INF?d[e]:-1);
}
int main(){
    int i,j,a,b,c;
    while(scanf("%d%d",&n,&m)!=EOF){
        for(i=0;i<n;i++)for(j=0;j<n;j++)mp[i][j]=INF;
        for(i=0;i<m;i++){
            scanf("%d%d%d",&a,&b,&c);
            if(mp[a][b]>c) mp[a][b]=mp[b][a]=c;
        }
        scanf("%d%d",&s,&e);
        SPFA();
    }
    return 0;
}

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/u013899738/article/details/47146555
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞