dij优化

普通的Dijkstra算法复杂度为n平方,当数据量稍大时就会超时,所以诞生了时间复杂度为nlogn的优先队列优化的Dijkstra算法。
原来版本有大量时间浪费在通过邻接矩阵找边和搜索当前最短路径中,而优化后的算法中,用结构体Edge存储边信息,省却了找有效边的麻烦。而且采用优先队列,可以快速找到最短路径,又省却一部分时间,所以在时间上具有极强的优越性。
贴一份代码,看输入部分代码相信应该可以看明白输入要求:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1000010;

struct qnode {
    int v;//结点编号
    int c;//到起点距离
    qnode(int _v = 0, int _c = 0) : v(_v), c(_c) {};

    bool operator<(const qnode &r) const {
        return c > r.c;
    }
};

struct Edge {
    int v, cost;//边的终点和权值
    Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost) {}
};

vector<Edge> E[maxn];
//可以理解为二维的,每个E可以包含若干项,这些项是以当前编号点为起点,
//若干项边结构体(Edge)的v为终点,cost为权值的边
bool vis[maxn];//是否访问
int dist[maxn];//距离
void dijkstra(int n, int start) {
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++) {
        dist[i] = inf;
    }
    priority_queue<qnode> que;
    //按照结点到起点距离大小作为出队列依据,距离最近先出
    //毕竟更新的时候是当前最短距离点作为中介更新其他点
    dist[start] = 0;
    que.push(qnode(start, 0));
    qnode tmp;
    while (!que.empty())//广搜找通路
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if (vis[u]) continue;
        vis[u] = true;
        for (int i = 0; i < E[u].size(); i++) {
            int v = E[tmp.v][i].v;
            //以tmp为起点的所有边中,找到另一个端点(方便起见叫做终点)
            //因为全部是边结构体,所以不需要遍历寻找,只要尝试更新就可以
            //vector本身就是向量,里面包含许多项,这里依次选取第i条边
            int cost = E[u][i].cost;
            if (!vis[v] && dist[v] > dist[u] + cost)//更新条件
            {
                dist[v] = dist[u] + cost;
                que.push(qnode(v, dist[v]));//为了不重,要求!vis[v],而且处理完进入队列进行下一次筛选
            }
        }
    }
}

void addedge(int u, int v, int w) {
    E[u].push_back(Edge(v, w));//输入边
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    while (m--) {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        addedge(a, b, c);
    }
    dijkstra(n, 1);
    printf("%d\n", dist[n]);
    return 0;
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是使用堆优化Dijkstra 算法来求解最短路径的示例代码,其中使用了 vector 来表示图的邻接表: ```cpp #include <iostream> #include <vector> #include <queue> #include <limits> using namespace std; typedef pair<int, int> pii; const int INF = numeric_limits<int>::max(); vector<int> dijkstra(const vector<vector<pii>>& graph, int source) { int n = graph.size(); vector<int> dist(n, INF); dist[source] = 0; priority_queue<pii, vector<pii>, greater<pii>> pq; pq.push({0, source}); while (!pq.empty()) { int u = pq.top().second; int d = pq.top().first; pq.pop(); if (d > dist[u]) { continue; // 已经找到了更短的路径 } for (const auto& edge : graph[u]) { int v = edge.first; int w = edge.second; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.push({dist[v], v}); } } } return dist; } int main() { int n = 5; // 图的顶点数 int m = 7; // 图的边数 vector<vector<pii>> graph(n); // 构建图的邻接表 graph[0].push_back({1, 2}); graph[0].push_back({2, 4}); graph[1].push_back({2, 1}); graph[1].push_back({3, 7}); graph[2].push_back({3, 3}); graph[2].push_back({4, 5}); graph[3].push_back({4, 2}); graph[4].push_back({3, 1}); int source = 0; vector<int> dist = dijkstra(graph, source); cout << "Shortest distances from node " << source << ":" << endl; for (int i = 0; i < n; ++i) { cout << "Node " << i << ": " << dist[i] << endl; } return 0; } ``` 上述代码中,我们使用堆优化Dijkstra 算法来找到从源节点到其他节点的最短距离。图的邻接关系使用 vector<vector<pii>> 来表示,其中 pii 表示边的目标节点和权重。你可以根据需要修改图的顶点数、边数和邻接表来适应不同的场景。输出结果将会显示源节点到其他节点的最短距离。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值