最短路的两种解法Dijkstra和spfa

最短路算法

问题描述

在加权图上,两点之间的最小边权和路径称为最短路径。

常用算法

Dijkstra算法

Dijkstra算法本质上可以看做一种贪心算法,即每次由已定最短路点集找出最小拓展点,并把最小拓展点并入最短路点集。

对于Dijkstra的正确性的证明,我们先证明以下引理:

**引理:**对于一个连通的最短路点集,从点集中拓展出的不在最短路点集的最短点,一定是该点的最短点。

证明:用反证法(具体就不写了)

代码:

struct Node{
    int id,dist;
}
Node makeNode(int id,int dist){
    Node now;
    now.id=id;now.dist=dist;
    return now;
}
priority_queue<Node>q;
void Dijkstra(int s){
    memset(use,0,sizeof use);
    while(!q.empty()) q.pop();
    for(int i=1;i<=n;++i) dis[i]=IFF;
    q.push(makeNode(s,dis[s]=0));
    while(!q.empty()){
        Node now=q.top();q.pop();
        if(now.dist<dis[now.id]||use[now.id]) continue;
        use[now.id]=1;
        for(int i=head[now.id];i;i=edge[i].pre){
            int fr=now.id,to=edge[i].to;
            if(dis[to]<=dis[fr]+edge[i].w) continue;
            dis[to]=dis[fr]+edge[i].w;
            q.push(makeNode(to,dis[to]));
        }
    }
}

队列优化的贝尔福特曼 s p f a spfa spfa

代码如下

queue<int>q;
void spfa(int s){
    memset(use,0,sizeof use);
    while(!q.empty()) q.pop();
    for(int i=1;i<=n;++i)
        dis[i]=IFF;
    dis[s]=0;q.push(s);use[s]=1;
    while(!q.empty()){
        int now=q.front();q.pop();
        use[now]=0;
        for(int i=head[now];i;i=edge[i].pre){
            int to=edge[i].to;
            if(dis[to]<=dis[now]+edge[i].val) continue;
            dis[to]=dis[now]+edge[i].val;
            if(!use[to]){
                use[to]=1;
                q.push(to);
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值