zoukankan      html  css  js  c++  java
  • 最短路板子

    堆优化dij

    • Dijkstra基于贪心思想,指适用为边权都是非负数的图
    • 而且这样写不能用于求最长路,需要进行优化,求最长路可以用SPFA
      • 最长路没有子结构,子段最长不一定总的最长。如图:

    Code

    priority_queue< pair<int, int> > q;
    //这里两个'>'尽量不要写在一起,有的编译环境会CE
    int d[N]; 
    bool v[N];
    void dij(int u) {
        memset(v, 0, sizeof(v));
        memset(d, 0x3f, sizeof(d));
        d[u] = 0;
        q.push(make_pair(0, u));
        while (!q.empty()) {
            int x = q.top().second; q.pop();
            if (v[x]) continue;
            v[x] = 1;
            for(int i = head[x]; i; i = e[i].next) {
                int y = e[i].t;
                if (d[y] > d[x] + e[i].d) {
                    d[y] = d[x] + e[i].d;
                    q.push(make_pair(-d[y], y));
                    //默认是从大到小排序,变成负数后就是从小到大了
                }
            }
        }
    }
    

    spfa

    • SPFA在随机图上时间效率为(O(km))级别, 其中(k)是个较小的常数
      但在特殊构造的图上,可能会退化为(O(nm)),必须谨慎使用

    Code

    queue<int> q;
    void Spfa(int u) {
        memset(d, 0x3f, sizeof(d));
        d[u] = 0;
        q.push(u); v[u] = 1;
        while (!q.empty()) {
            int x = q.front();
            q.pop(); v[x] = 0;
            for (int i = head[x]; i; i = e[i].next) {
                int y = e[i].t;
                if (d[y] > d[x] + e[i].d) {
                    d[y] = d[x] + e[i].d;
                    if (v[y]) continue;
                    q.push(y); v[y] = 1;
                }
            }
        }
    }
    
    

    双端队列优化spfa

    • SPFA还可以通过双端队列进行SLF优化(改变的地方我都有标注)

    Code

    deque<int> q;
    void Spfa(int u) {
        memset(d, 0x3f, sizeof(d));
        d[u] = 0;
        q.push_back(u); v[u] = 1;//这里
        while (!q.empty()) {
            int x = q.front();
            q.pop_front(); v[x] = 0;//这里
            for (int i = head[x]; i; i = e[i].next) {
                int y = e[i].t;
                if (d[y] > d[x] + e[i].d) {
                    d[y] = d[x] + e[i].d;
                    if (v[y]) continue;
                    if (d[y] <= d[q.front()]) q.push_front(y);
                    //这里是最主要的地方,加入的元素如果比队首小,就放在队首
                    else q.push_back(y); //这里
                    v[y] = 1;
                }
            }
        }
    }
    
  • 相关阅读:
    Ubuntu apt常用命令
    PHP 图片操作(按照指定尺寸压缩,按照比例裁剪)
    Django简介
    浅议SNMP安全、SNMP协议、网络管理学习
    Linux下dmesg命令处理故障和收集系统信息的7种用法
    syslog之三:建立Windows下面的syslog日志服务器
    syslog之二:syslog协议及rsyslog服务全解析
    syslog之一:Linux syslog日志系统详解
    syslog简单配置介绍
    ethtool工具使用实例
  • 原文地址:https://www.cnblogs.com/shawk/p/12964829.html
Copyright © 2011-2022 走看看