zoukankan      html  css  js  c++  java
  • spfa及slf优化

    spfa,不用多讲了吧,相当实用的BF队列优化算法,裸代码如下

    program spfa;
    var    pre,last,other,long:array[0..1000001] of longint;
        d,short:array[0..1000001] of longint;
        ok:array[0..1000001] of boolean;
        head,tail,m,n,i,j,k,tot,x,y,z:longint;
    procedure add(x,y,z:longint);
    begin
        inc(tot);
        pre[tot]:=last[x];
        last[x]:=tot;
        other[tot]:=y;
        long[tot]:=z;
    end;
    begin
        readln(n,m);
        for i:=1 to m do
        begin
            readln(x,y,z);
            add(x,y,z);
            add(y,x,z);
        end;
        fillchar(ok,sizeof(ok),true);
        fillchar(short,sizeof(short),127);
        head:=0;
        tail:=1;
        d[1]:=1;
        short[1]:=0;
        while head<tail do
        begin
            inc(head);
            ok[d[head]]:=true;
            i:=last[d[head]];
            while i<>0 do
            begin
                if short[other[i]]>short[d[head]]+long[i] then
                begin
                    short[other[i]]:=short[d[head]]+long[i];
                    if ok[other[i]] then
                    begin
                        ok[other[i]]:=false;
                        inc(tail);
                        d[tail]:=other[i];
                    end;
                end;
                i:=pre[i];
            end;
        end;
        for i:=1 to n do writeln(short[i]);
    end.

    用这个程序轻松求出从标号1到各点的距离。

    如果起点不是1,又要怎么做呢?

    1)暴力法

      很容易想到,数组存下所有边的起点,中点及权值,再将所有点权加上(n-x) mod n + 1,其中n表示点数,x表示所求起点。

      正确性显然,就不多证明了。

    2)更改spfa主要部分如下:

      ①将队首元素更改为所求节点

      ②由该点向外拓展至各边并比较,记录

      由此,我们将一个spfa变成了可以求从任意起点到其他点最短路的算法

      代码就不贴了,大家可以自己写一下,利用上面的可以直接改变量,或者把主要部分放进procedure里

    3)slf优化

      详见百度百科,大家可以自行查找,通过将部分点放于队首减少更新的算法优化,代码贴c++了,DeAR神犇手打

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    //variable//
    int last[100000],prel[100000],dest[100000],cost[100000],tot=1;
    int vis[100000],q[1000000],dis[100000];
    
    //function prototype//
    void addline(int,int,int);
    void spfa_slf(int);
    
    //solve//
    int main(){
        int n,m,u,v,w;
        scanf("%d%d",&n,&m);
        for (int i=0;i<m;++i){
            scanf("%d%d%d",&u,&v,&w);
            addline(u,v,w);
        }
        spfa_slf(1);
        printf("%d
    ",dis[n]);
        system("pause");
        return 0;
    }
    
    void addline(int u,int v,int w){
        dest[++tot]=v;
        prel[tot]=last[u];
        last[u]=tot;
        cost[tot]=w;
    }
    
    void spfa_slf(int x){
        memset(dis,0x7f,sizeof dis);
        memset(vis,0,sizeof vis);
        int he=500000,ta=500000;
        dis[x]=0;vis[x]=1;q[he]=x;
        while (he<=ta){
            int u=q[he++];
            vis[u]=0;
            for (int k=last[u];k;k=prel[k]){
                if (dis[dest[k]]>dis[u]+cost[k]){
                    dis[dest[k]]=dis[u]+cost[k];
                    if (!vis[dest[k]]){
                        vis[dest[k]]=1;
                        if (dis[dest[k]]<dis[u]){
                            q[--he]=dest[k];
                        }else{
                            q[++ta]=dest[k];
                        }
                    }
                }
            }
        }
    }
  • 相关阅读:
    抽样调查
    一次项目上线发布的感想
    Nginx failing to load CSS and JS files (MIME type error)
    securecrt-active
    golang-http-post
    remove-weknow-ac from mac chrome
    批量写入redis
    golang 修改数组中结构体对象的值的坑
    golang使用json生成结构体
    json定义
  • 原文地址:https://www.cnblogs.com/victorslave/p/4796081.html
Copyright © 2011-2022 走看看