最短路Dijkstra算法

呵呵😅,一年多没有写文章了。当然,这段时间我也没松懈。闭关了这么长时间回头一看我以前的文章......感觉好尬😓。

好了不多说了开始切入正题:

dij是一种最短路算法,时间复杂度是O(n^2)

dij的缺点是:不能处理负数。

dij的优点是:复杂度较低、理解起来更容易(个人觉得)。

dij的特点是:比较适合稀疏图。

原理:

给定起点,起点到起点的距离是0,开始以一种类似bfs的方法遍历周围的点(注意要把queue改成priority_queue),如果有更优解就把之前的撤掉改成更优解。

c++代码:

#include<iostream>
#include<queue>
#include<vector>
using namespace std;
struct node{
    int v,w;
    bool operator<(const node &a)const{
        return w>a.w;//重载小于符号(我们想让q从小到大比对所以要把"<"重载为">")
    }
};
bool vis[100005]={};//记录是否被访问过
vector<node>g[100005];
priority_queue<node>q;//优先队列
int dist[10005]={};
int main(){
    int n,m,s;
    cin>>n>>m>>s;
    for(int i=1;i<=m;i++){
        int u,v,w;
        cin>>u>>v>>w;
        g[u].push_back({v,w});//建图
    }
    memset(dist,0x3f,sizeof(dist));//把dist初始化成+∞
    q.push({s,0});//以s为起点,遍历整个图
    dist[s]=0;//s->s的距离是0
    while(!q.empty()){//如果q不空就代表还有东西没完
        int x=q.top().v;//当前遍历点为x
        q.pop();//q弹出,不然死循环
        if(vis[x])continue;//判断是否走过
        for(int i=0;i<g[x].size();i++){//遍历x的每一条边
            if(dist[g[x][i].v]>dist[x]+g[x][i].w){//如果从这里走更优那就把dist更新(如果vis写在这里就会出很严重的问题——每个点只会遍历一次,无法选择最优解)
                dist[g[x][i].v]=dist[x]+g[x][i].w;//更新
                q.push({g[x][i].v,dist[g[x][i].v]});//把结果放进去
            }
        }
    }
    //输出
    for(int i=1;i<=n;i++){
        if(dist[i]==0x3f3f3f3f){
            cout<<"此路不通"<<endl;
            continue;
        }
        cout<<dist[i]<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值