最短路径(由浅到深)

来源:互联网 发布:安云加速器for mac 编辑:程序博客网 时间:2024/06/05 13:21

                                                 最短路

哎,人生呀,之前一直排斥图,看来啊哈算法,和挑战编程后,发现自己突然有些明白了

第一 Floyd——Warshall

求任意两点之间的最短路径,也被称为多源最短N路径

方法一,用深搜和光搜,对每两个点进行一次搜索,便可求得

方法二,用Floyd—Warshall来解决

首先需要数据结构来存储图,用邻接矩阵来储存,如果求两点之间最短距离,就是要比较两点之间的直接距离(a到b),和间接距离(即引入其他点,如a到c,c到b,或者a到的,d到e,e到b),找出最短距离,由此可知,找i,j的最短路,就是找i到看,k到j距离和与到j的距离中的最小距离

即 核心思想

e[i][j]表示从i到j点的距离n 代表多小个顶点for(int k=1; k<=n; k++){    for(int i=1; i<=n; i++)    {        for(int j=1; j<=n; j++)        {            if(e[i][j]>e[i][k]+e[k][j]&&e[i][k]<INFINF&&e[k][j]<INF)                e[i][j]=e[i][k]+e[k][j];        }    }}
时间复杂度 (n^3)

第二 Dijkstra算法——单源最短路

算法思想 :每次找到离源点最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余 所有点的最短路径

基本步骤

1.将所有的顶点分为两部分,已知最短路径的顶点集合P和未知最短路径的顶点集合Q,用一个数组book[i]表示: book[i]=1代表顶点i在集合p中,book[i]=0代表顶点i在集合Q中。

2设置源点s到自己的最短路径为0,即dis[s]=0.若存在有源点能直接到达的顶点i,把dis[i]设为e[s][i],.同时把所有其他(源点不能直接到达的)顶点的最短路径设为无穷

3 在集合Q的所有顶点中选择一个离源点s最近的顶点u(即dis[u]最小)加入到集合P,并开始考察所有以点u为起点的边,对每一边找最短距离(例如 u到v的边,比较dis[v]与dis[u]+e[u][v]的值,dis[v]=min(dis[v],dis[u]+e[u][v])

4 重复第3步,如果集合为空,结束,dis数组存的是源点到所有·顶点的最短路径

如下

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <string>#include <map>using namespace std;const int MAXN = 10005;#define INF 99999999int n,m,minn,u,v;int book[MAXN];int dis[MAXN];int e[MAXN][MAXN];void init(){    //初始化book    for(int i=0;i<=n;i++)        book[i]=0;    //创建图,邻接矩阵    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(i==j)                e[i][i]=0;            else                e[i][j]=INF;        }    }}void fun(){     for(int i=1;i<=n;i++)    {        dis[i]=e[1][i];    }}void Dijkstra()//核心算法{    for(int i=1;i<=n-1;i++)    {        minn=INF;        for(int j=1;j<=n;j++)        {            if(book[j]==0&&dis[j]<minn)            {                minn=dis[j];                u=j;            }        }        book[u]=1;        for(v=1;v<=n;v++)        {            if(e[u][v]<INF)            {                if(dis[v]>dis[u]+e[u][v])                {                    dis[v]=dis[u]+e[u][v];                }            }        }    }}int main(){    int t1,t2,t3;    scanf("%d%d",&n,&m);    init();    for(int i=0;i<m;i++)    {        scanf("%d%d%d",&t1,&t2,&t3);        e[t1][t2]=t3;    }    fun();    book[1]=1;    Dijkstra();    for(int i=1;i<=n;i++)    {        printf("%d ",dis[i]);    }    printf("\n");    getchar();    getchar();    return 0;}


0 0
原创粉丝点击