• bzoj 2662&bzoj 2763 SPFA变形


    我们用dis[i,j]代表到i这个点,用j张票的最短路程,那么我们只需要在SPFA更新

    的时候,用dis[i,j]更新dis[p,j]和dis[p,j+1]就行了

    /**************************************************************
        Problem: 2662
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:4 ms
        Memory:376 kb
    ****************************************************************/
     
    //By BLADEVIL
    type
        rec                         =record
            x, use                  :longint;
        end;
         
    var
        n, m, k                     :longint;
        pre, other, len             :array[0..2010] of longint;
        last                        :array[0..100] of longint;
        l                           :longint;
        dis                         :array[0..100,0..100] of longint;
        flag                        :array[0..100,0..100] of boolean;
        que                         :array[0..10000] of rec;
        ans                         :longint;
         
    function min(a,b:longint):longint;
    begin
        if a>b then min:=b else min:=a;
    end;
         
    procedure connect(x,y,z:longint);
    begin
        inc(l);
        pre[l]:=last[x];
        last[x]:=l;
        other[l]:=y;
        len[l]:=z;
    end;
         
    procedure init;
    var
        i                           :longint;
        x, y, z                     :longint;
    begin
        read(n,m,k);
        for i:=1 to m do
        begin
            read(x,y,z);
            connect(x,y,z);
            connect(y,x,z);
        end;
    end;
     
    procedure main;
    var
        h, t, q, p                  :longint;
        cur, ti                     :longint;
        i                           :longint;
         
    begin
        filldword(dis,sizeof(dis) div 4,maxlongint div 10);
        dis[1,0]:=0;
        h:=0; t:=1;
        que[1].x:=1; que[1].use:=0;
        while h<>t do
        begin
            h:=h mod 10000+1;
            cur:=que[h].x;
            ti:=que[h].use;
            flag[cur,ti]:=false;
            q:=last[cur];
            while q<>0 do
            begin
                p:=other[q];
                if dis[cur,ti]+len[q]<dis[p,ti] then
                begin
                    dis[p,ti]:=dis[cur,ti]+len[q];
                    if not flag[p,ti] then
                    begin
                        t:=t mod 10000+1;
                        que[t].x:=p; que[t].use:=ti;
                        flag[p,ti]:=true;
                    end;
                end;
                if ti<k then
                begin
                    if dis[cur,ti]+len[q] div 2<dis[p,ti+1] then
                    begin
                        dis[p,ti+1]:=dis[cur,ti]+len[q] div 2;
                        if not flag[p,ti+1] then
                        begin
                            t:=t mod 10000+1;
                            que[t].x:=p; que[t].use:=ti+1;
                            flag[p,ti+1]:=true;
                        end;
                    end;
                end;
                q:=pre[q];
            end;
        end;
        ans:=maxlongint;
        for i:=0 to k do ans:=min(ans,dis[n,i]);
        writeln(ans);
    end;
     
    begin
        init;
        main;
    end.
    /**************************************************************
        Problem: 2763
        User: BLADEVIL
        Language: Pascal
        Result: Accepted
        Time:9472 ms
        Memory:2804 kb
    ****************************************************************/
     
    //By BLADEVIL
    type
        rec                         =record
            x, use                  :longint;
        end;
         
    var
        n, m, k                     :longint;
        pre, other, len             :array[0..100010] of longint;
        last                        :array[0..10010] of longint;
        l                           :longint;
        dis                         :array[0..10000,0..11] of longint;
        flag                        :array[0..10000,0..11] of boolean;
        que                         :array[0..100010] of rec;
        ans                         :longint;
        st, fin                     :longint;
         
    function min(a,b:longint):longint;
    begin
        if a>b then min:=b else min:=a;
    end;
         
    procedure connect(x,y,z:longint);
    begin
        inc(l);
        pre[l]:=last[x];
        last[x]:=l;
        other[l]:=y;
        len[l]:=z;
    end;
         
    procedure init;
    var
        i                           :longint;
        x, y, z                     :longint;
    begin
        read(n,m,k);
        read(st,fin);
        for i:=1 to m do
        begin
            read(x,y,z);
            connect(x,y,z);
            connect(y,x,z);
        end;
    end;
     
    procedure main;
    var
        h, t, q, p                  :longint;
        cur, ti                     :longint;
        i                           :longint;
         
    begin
        filldword(dis,sizeof(dis) div 4,maxlongint div 10);
        dis[st,0]:=0;
        h:=0; t:=1;
        que[1].x:=st; que[1].use:=0;
        while h<>t do
        begin
            h:=h mod 100000+1;
            cur:=que[h].x;
            ti:=que[h].use;
            flag[cur,ti]:=false;
            q:=last[cur];
            while q<>0 do
            begin
                p:=other[q];
                if dis[cur,ti]+len[q]<dis[p,ti] then
                begin
                    dis[p,ti]:=dis[cur,ti]+len[q];
                    if not flag[p,ti] then
                    begin
                        t:=t mod 100000+1;
                        que[t].x:=p; que[t].use:=ti;
                        flag[p,ti]:=true;
                    end;
                end;
                if ti<k then
                begin
                    if dis[cur,ti]<dis[p,ti+1] then
                    begin
                        dis[p,ti+1]:=dis[cur,ti];
                        if not flag[p,ti+1] then
                        begin
                            t:=t mod 100000+1;
                            que[t].x:=p; que[t].use:=ti+1;
                            flag[p,ti+1]:=true;
                        end;
                    end;
                end;
                q:=pre[q];
            end;
        end;
        ans:=maxlongint;
        for i:=0 to k do ans:=min(ans,dis[fin,i]);
        writeln(ans);
    end;
     
    begin
        init;
        main;
    end.
  • 相关阅读:
    test
    TCP/IP状态转换图
    用Python操作Excel,实现班级成绩的统计
    树莓派介绍和安装树莓派系统遇到的坑,好痛苦啊
    Eclipse-jee-oxygen-3A版运行时出现Could not create the Java virtual machine?
    eclipse搭建简单的web服务,使用tomcat服务
    嵌入式【杂记--手机芯片与pc】
    tomcat启动不了?
    Selenium的使用
    使用PhantomJS
  • 原文地址:https://www.cnblogs.com/BLADEVIL/p/3483924.html
Copyright © 2020-2023  润新知