最短路径(由浅到深)

                                                 最短路

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

第一 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]
时间复杂度 (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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
const int MAXN = 10005;
#define INF 99999999
int 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]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


你可能感兴趣的:(最短路径(由浅到深))