最短路问题

家住魔仙堡 提交于 2019-11-27 03:40:24

最短路问题
有4种算法+广搜
分为单源最短路和多源最短路

  • floyd算法 多源最短路 O(n^3)
  • Dijkstra 单源最短路 O
  • ford算法
  • johnson算法

优化算法

  • SPFA算法 单源最短路 O(n^2)ford算法的队列优化算法

而最短路问题又有很多种,比如

  • 最小环
  • 哈密顿回路
  • 最小生成树

弗洛伊德算法Floyd

https://blog.csdn.net/Harington/article/details/81982299

定义g[i][j]表示i到j的最短路径,k是中介,i通过k到达j,指的是,只允许经过第k个结点

for(int k=1;k<=n;k++){
    for(int i=1;i<=n;i++){
        if(g[i][k]==INF)continue;//优化时间复杂度
        for(int j=1;j<=n;j++){
            if(g[i][j]>g[i][k]+g[k][j]){
                g[i][j]=g[i][k]+g[k][j];
            }
        }
    }
}

时间复杂度是O(n^3),对于大数据不合适,适合与n在100以内的数据

第一行输入结点数n和边数m
接下来的m行输入无向边情况
表示u与v相互连接,且距离为d,路费为p
最后输入a,b,求a到b的最短距离,当距离有多条时,输出路费最小的

利用Floyd算法实现多源最短路

本代码没有实现距离多条时,输出路费最小,且n<1000,m<10000;对于O(n^3)时间太慢

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1005;
const int INF=10000000;
int g[maxn][maxn];
int mo[maxn][maxn];
int main(){
    int n,m;
    while(scanf("%d%d",&n,&m)==2&&n&&m){

        for(int i=1;i<=n;i++){//初始化
            for(int j=1;j<=n;j++){
                g[i][j]=INF;
            }
        }

        for(int i=0;i<m;i++){
            int u,v,d,p;
            scanf("%d%d%d%d",&u,&v,&d,&p);
            g[u][v]=d;
            g[v][u]=d;

            mo[u][v]=p;
            mo[v][u]=p;
        }

        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                if(g[i][k]==INF)continue;
                for(int j=1;j<=n;j++){
                    if(g[k][i]==INF)continue;
                    if(g[i][j]>g[i][k]+g[k][j]){
                        g[i][j]=g[i][k]+g[k][j];
                        mo[i][j]=mo[i][k]+mo[k][j];
                    }

                }
            }
        }

        int s,t;
        scanf("%d%d",&s,&t);
        printf("%d %d\n",g[s][t],mo[s][t]);

    }

    return 0;

}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!