dijistra算法

一,简介

dijistra算法是求从源点开始u到其他点的最短路径问题。前提条件是带权值的边。权值为正数。

1.将每个点的距离设为无穷大,彼此都不连通。将这些点的集合设为S.

2.另一个集合为V。从源点s开始,距离设为0,放到集合V中。

3.设每条边是<u,v>。则通过dist(v) = min{dis(v),dist(u) + l(u,v)} 进行松弛操作。选取最小代价的点,放到集合V中,直到集合S中的元素被拿光结束。

二,代码


void dijistra1(int u){
    int inf = 0x3f3f3f3f;//无穷边
    memset(trackPath, -1, sizeof(trackPath));//记录u到其他顶点的最短路径
    memset(path, inf, sizeof(path));//记录u到其他顶点的最短路径
    memest(rec, false, sizeof(rec));//记录那些点已经计算了,放到了集合V中
    path[u] = 0;//自己到自己距离为0
    int m;
    for(int i = 0; i <= n; i++){
        for(int j = 1, m = inf; j <= n; j++){
            if(!rec[j] && path[j] < m){
                m = path[j];
                u = j;
            }
        }
        rec[u] = true;
        for(int k = 1; k <= n; k++){
            if(!rec[k]){
            //松弛操作
                path[k] = min(path[k], path[u] + g[u][k]);
                trackPath[k] = u;//记录最短路径u到k,k的前驱:可以追踪最短路径的线路
            }
        }
    }
}

堆优化

堆优化的主要思想就是使用一个优先队列(就是每次弹出的元素一定是整个队列中最小的元素)来代替最近距离的查找,用邻接表代替邻接矩阵,这样可以大幅度节约时间开销,就是对下面的代码进行优化,使用优先队列,就不用每次O(n)查找,效率O(nlogn)

for(int j = 1, m = inf; j <= n; j++){
            if(!rec[j] && path[j] < m){
                m = path[j];
                u = j;
            }
        }
struct Node{
    int u, dis;
    Node(int u, int dis): u(u), dis(dis){}
    bool operator < (const Node& t) const{//重小到大排序
        return dis > t.dis;
    }
}
void dijistra2(int u){
    memset(path, inf, sizeof(path));
    memset(rec, false, sizeof(rec));
    memset(trackPath, -1, sizeof(trackPath));//记录u到其他顶点的最短路径
    path[u] = 0;
    priority_queue<Node>q;
    q.push(Node(u, 0));
    while(q.empty()){
        int uu = q.top().u;
        q.pop();
        if(rec[uu]) continue;
        rec[uu] = true;
        for(int k = 1; k <= n; k++){
            if(!rec[k] && path[k] > path[uu] + g[uu][k]){
				path[k] = path[uu] + g[uu][k];
				q.push(Node(k, path[k]));
				trackPath[k] = uu;
			}
     
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值