P4568 [JLOI2011]飞行路线

用高度来限制 \(K\),这个很好理解,看第一位的图可知了。

当然 \(DP\) 也是可以的。

手写堆 \(7.in\) 会炸掉! 因为会有 \(heap_{num} \leq 0\) 的时候!

// luogu-judger-enable-o2
// T1

Uses math;

var
    next,rope,from,value,reach:array[-1..21000000] of longint;
    heap,node:array[-1..21000000] of longint;
    dis,cnt:array[-1..510000] of longint;
    id:array[-1..510000,-1..11] of longint;
    ask:array[-1..510000] of boolean;
    l,r,k,i,j,n,m,num,tot,free,sink,source:longint;

procedure swap(var a,b:longint);var t:longint; begin t:=a; a:=b; b:=t; end;

procedure add(l,r,sum:longint);
begin
    inc(tot); from[tot]:=l; reach[tot]:=r; value[tot]:=sum; next[tot]:=cnt[l]; cnt[l]:=tot;
end;

procedure Insert(x:longint);
var father:longint;
begin
    if x=1 then exit;
    father:=x >> 1;
    if heap[father]>heap[x] then
    begin
        swap(heap[x],heap[father]); swap(node[x],node[father]);
        Insert(father);
    end;
end;

procedure Down(x:longint);
var son:longint;
begin
    if x << 1>num then exit;
    son:=x << 1;
    if (son+1<=num)and(heap[son+1]<=heap[son]) then inc(son);
    if heap[x]>heap[son] then begin swap(heap[x],heap[son]); swap(node[x],node[son]); end;
    Down(son);
end;

procedure Dijkstar;
var i,key,rope:longint;
begin
    fillchar(ask,sizeof(ask),0);
    rope:=0; dis[source]:=0; num:=0;
    for i:=1 to free do
    begin
        inc(num); heap[num]:=dis[id[source,i]]; node[num]:=id[source,i];
        Insert(num);
    end;
    repeat
        key:=node[1];
        heap[1]:=heap[num]; node[1]:=node[num];
        dec(num); down(1);
        if ask[key]=False then
        begin
            inc(rope); ask[key]:=True;
            i:=cnt[key];
            while i<>-1 do
            begin
                if (dis[reach[i]]>value[i]+dis[key]) then
                begin
                    dis[reach[i]]:=value[i]+dis[key];
                    inc(num); heap[num]:=dis[reach[i]]; node[num]:=reach[i];
                    Insert(num);
                end;
                i:=next[i];
            end;
        end;
    until rope=n*free;
end;

begin
    filldword(dis,sizeof(dis) div 4,maxlongint div 84);
    filldword(cnt,sizeof(cnt) div 4,maxlongint*2+1);
    filldword(heap,sizeof(heap) div 4,0);
    read(n,m,free,source,sink);
    inc(free); inc(source); inc(sink);
    for j:=1 to free do for i:=1 to n do id[i,j]:=(j-1)*n+i;
    for j:=1 to free do dis[id[source,j]]:=0;
    for i:=1 to m do
    begin
        read(l,r,k); inc(l); inc(r);
        for j:=1 to free do begin add(id[l,j],id[r,j],k); add(id[r,j],id[l,j],k); end;
        for j:=1 to free-1 do begin add(id[l,j],id[r,j+1],0); add(id[r,j],id[l,j+1],0); end;
    end;
    Dijkstar;
    writeln(dis[id[sink,free]]);
end.
posted @ 2019-01-25 21:46  _ARFA  阅读(158)  评论(0编辑  收藏  举报