单源最短距离问题(Bellman-Ford和Dijkstra)

单源最短距离:固定一个起点,计算它到其他点的最短距离的问题。

1.Bellman-Ford算法

记录从源点s出发到点i的最短距离为d[i],利用d[i]=min{d[j]+edge(j,i), d[i]}不断更新数组d

一开始设置距离源点s的距离d[s]=0,到其他点的距离d[i]=INF,利用上面的递推式更新数组,只要图中没有负圈,更新的次数就是有限次的

#define INF 1<<28
static const int MAX = 10050;

struct edge{
    int from, to, cost;
};

edge es[MAX];   //边
int d[MAX]; //距源点的最短距离
int V;  //顶点数
int E;  //边数

//Bellman-Ford
void shortest_path(int s)
{
    for (int i = 0; i < V; i++)
        d[i] = INF;
    d[s] = 0;

    while (1)
    {
        bool update = false;    //更新标记
        //更新距离
        for (int i = 0; i < MAX; i++)
        {
            edge e = es[i];
            if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost)
            {
                update = true;
                d[e.to] = d[e.from] + e.cost;
            }
        }
        if (!update)
            break;
    }
}

 2.Dijkstra算法

利用Bellman-Ford算法,即使d[i]不是最短距离也有可能更新,即使d[i]没有变化,也会从头出发检查所有的边。所以对算法做了以下修改:

(1)找到最短距离确定的点,更新与它相邻的顶点

(2)对于在(1)确定的点,下次不再检查

#define INF 1<<28
static const int MAX = 10050;

struct edge{
    int from, to, cost;
};

edge es[MAX];   //边
int cost[MAX][MAX]; //cost[i][j]表示从i到j的权值,如果不存在则为INF
int d[MAX]; //距源点的最短距离
bool used[MAX]; //记录该点是否使用过
int V;  //顶点数
int E;  //边数

void dijkstra(int s)
{
    for (int i = 0; i < V; i++)
    {
        used[i] = false;
        d[i] = INF;
    }    
    d[s] = 0;
    while (1)
    {
        int v = -1;
        for (int i = 0; i < V; i++)
            if (!used[i] && ((v == -1) || d[v] > d[i]))
                v = i;
        if (v == -1)
            break;
        
        used[v] = true;
        for (int i = 0; i < V; i++)
            d[i] = min(d[i], d[v] + cost[v][i]);
    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值