求最短路问题

单源最短路

一、Dijkstra算法(O(n^2))

应用条件:

1、无环,2、无负权边  3、起点必须已知  4、节点个数不能过大

Dijkstra 算法主要解决的是单源最短路径问题。它的时间复杂度一般是o(n^2) ,因此相对于Floyd算法速度上有极大的优势,可以处理更多的数据。

思路:

1、遍历n次,确定n个点的最短距离

2、在每次遍历中,先找到没有确定最短距离的且到目前到初始点最短的点

3、用这个点去更新其它点

int dijkstra()
{
    memset(dist, 0x3f, sizeof dist);
    dist[1] = 0;//dist[]存放第i个点到初始点的最短距离

    for (int i = 0; i < n ; i ++ )//遍历n次,求出n个点的最短距离
    {
        int t = -1;//还没有确定到集合最短的点
        for (int j = 1; j <= n; j ++ )
            if (!st[j] && (t == -1 || dist[t] > dist[j]))
                t = j;

        for (int j = 1; j <= n; j ++ )
            dist[j] = min(dist[j], dist[t] + g[t][j]);

        st[t] = true;
    }

    if (dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}

二、Bellman-Ford算法

应用条件:

单源最短路径(从源点s到其它所有顶点v);

有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图);

边权可正可负(如有负权回路输出错误提示);

struct Edge
{
    int a, b, c;
}edges[M];

int bf()
{
    memset(dist,0x3f,sizeof dist);
    
    for(int k=1;k<n;k++)//最多经过k次中转
    {
        memcpy(last, dist, sizeof dist);//备份上一次
        for(int i=1;i<=m;i++)
        {
            auto e=eage[i];
            dist[e.b]=min(dist[e.b],dist[e.a]+e.w);
        }
    }
}

多源最短路

Floyd算法

void flyid()
{
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}

最短路径问题(更新)-CSDN博客

int fun()
{
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    
    queue<int> q;
    q.push(1);
    st[1]=1;
    
    while(q.size())
    {
        int t=q.front();
        q.pop();
        st[1]=0;
        
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[t]+w[i])
            {
                dist[j]=dist[t]+w[i];
                if(st[j]==0)
                {
                    q.push(j);
                    st[j]=1;
                    
                }
            }
        }
    }
    
    if(dist[n]==0x3f3f3f3f)
    return -1;
    else
    return dist[n];
}

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值