zoukankan      html  css  js  c++  java
  • Luogu P4779 【模板】单源最短路径(标准版)(Dijkstra+堆优化模板)

    qwq

    dij其实和prim挺像的,prim是找权值最小点,dij是找边,

    用一个优先队列就可以在加入边的时候直接排序,避免了每次遍历更新min

     priority_queue <pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;

    这句话就能把大根堆转化为小根堆(pair中的第一个值first最小的在最上面),

    同时pair<边权,序号>便于在对边权排序的同时调用这条边的序号。

    注意事项:

    1. 找点的时候要有一个vis标记是否访问过(剪枝)
    2. 加边的时候要注意是有向图还是无向图...

    代码如下

    #include<cstdio>
    #include<iostream>
    #include<queue>
    using namespace std;
    
    const int maxn = 500005;
    const int INF = 2147483647;
    int n,m,s,x,y,z,cnt;
    int to[maxn],next[maxn],head[maxn],val[maxn],dis[maxn];
    bool vis[maxn];
    
    void add(int x,int y,int z) {
        to[++cnt] = y;
        next[cnt] = head[x];
        head[x] = cnt;
        val[cnt] = z;
    }
    
    void dijkstra(int s) {
        priority_queue <pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
        dis[s] = 0;
        q.push(make_pair(0,s));
        while(!q.empty()) {
            int u = q.top().second;
            q.pop();
            if(vis[u])continue;
            vis[u] = 1;
            for(int i = head[u]; i; i = next[i]) {
                int v = to[i];
                if(dis[v] <= dis[u] + val[i]) continue;
                dis[v] = dis[u] + val[i];
                q.push(make_pair(dis[v],v));
            }
        }
        return;
    }
    
    int main() {
        scanf("%d%d%d",&n,&m,&s);
        for(int i = 1; i <= m; i++) {
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        for(int i = 1; i <= n; i++)
            dis[i] = INF;
        dijkstra(s);
        for(int i = 1; i <= n; i++)
            cout << dis[i] << ' ';
        return 0;
    }

     

  • 相关阅读:
    密码等级
    ie兼容透明
    分割线
    支付宝银行判断接口
    date只能选择今天之后的时间js
    离开页面之前提示,关闭,刷新等
    使用 Linux 系统的常用命令
    C#窗体简单增删改查
    1
    二维数组
  • 原文地址:https://www.cnblogs.com/mogeko/p/10046758.html
Copyright © 2011-2022 走看看