最短路算法c++(dijsktra,floyd,spfa)

floyd,复杂度O(n^3)

void floyd(int s,int e)//start end
{
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(g[i][j]>g[i][k]+g[k][j])
                    g[i][j]=g[i][k]+g[k][j];
    cout<<g[s][e]<<endl;
}

dijsktra O((n+m)logn) 

struct Node{
    int to,dis;
};//携带边的终边,长度信息
vector<Node> g[maxn];
void add(int u,int v,int w)
{
    g[u].push_back({v,w});
}
int dis[maxn];//最短路数组
typedef pair<int,int> P;//将int,int型数据重命名为P
void dij(int start){
    memset(dis,0x3f,sizeof(dis));//初始最短路为inf
    priority_queue<P,vector<P>,greater<P> > q;//小根堆,堆顶是最小值
    dis[start]=0;//起点自己距离为0
    q.push(P(0,start));//起点入队,注意pair数组第一个是距离,第二个是点号
    while(!q.empty()){
        P p=q.top(); q.pop();//取出堆顶
        int u=p.second;
        if(dis[u]<p.first)        continue;
        //祖传优化,同一点可能多次入队,如果答案更劣可以舍弃
        for(int i=0;i<g[u].size();i++){//邻接表遍历
            int v=g[u][i].to;
            if(dis[v]>dis[u]+g[u][i].dis){//松弛
                dis[v]=dis[u]+g[u][i].dis;//成功了就更新,入队
                q.push(P(dis[v],v));
            }
        }
    }
    return ;
}

spfa O(nm)

bool spfa(int st)
{
    vector<int> dis(n,inf), vis(n, 0), cnt(n, 0);
    dis[st] = 0;
    vis[st] = 1;
    queue<int> q;
    q.emplace(st);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for(auto [v, w] : g[u])
        {
            if(dis[v] > dis[u] + w)
            {
                dis[v] = dis[u] + w;
                cnt[v] = cnt[u] + 1;
                if(cnt[v] >= n)
                    return false;
                if(!vis[v])
                {
                    q.emplace(v);
                    vis[v] = 1;
                }
            }
        }
    }
    return true;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值