您的位置:首页 > Web前端

bzoj 1579 [Usaco2009 Feb]Revampi…

2014-12-29 08:36 211 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1579
http://poj.org/problem?id=3635
两题实在长,我就不贴了。

这两题的做法都是一样的,在dij的时候多加一维分别表示当前剩余的更新次数(poj里面是余油量)。

很多人都是开个二维数组搞的,但是今天看到一个拆点的做法相当神奇~~原文地址如下:
http://hi.baidu.com/lrc2222/blog/item/e40177f76c37b338720eecc7.html
大意就是把n个点分成k层,k即原方法中的第二位,然后把0长度的边连在不同的层之间表示更新路径使时间为0,相同层里面的点连原时间长度的边表示不更新路径直接走。最后在每一层里面的终点值里取个最优的输出。

对于poj里面的那题所连的边都是在不同层之间的。向较上一层的自己连一条长度为一单位油价的边表示加油,向下d层的j点连一条权值为0的边表示有一条长度为d的路与j连接。

这样建完图就是裸裸的dij+heap了~~~

不过poj上的那题一早上总是超时。。。怎么卡时都不过。。。后来看标程发现一个露加的优化:

当第0层的终点有值的时候就退出。

因为用的是dij,正确性显而易见。。。

但是bzoj上的那道题就不能用这个优化了。。。有可能k次更新不许要都用完就已经走到了。。。

这里就贴一个poj上的代码吧、、

AC
CODE

{$inline on}

program pku_3635;

const maxn=99999999;

var line,next,g:array[1..2100000] of longint;

   
en,dist,pi,heap:array[1..101000] of longint;

   
c:array[1..1000] of longint;

   
lim,s,t,n,len,tot,capa:longint;

//=========================================================================

procedure ins(x,y,z:longint); inline;

begin

  inc(len); line[len]:=y; g[len]:=z;

  next[len]:=en[x]; en[x]:=len;

end;

//=========================================================================

procedure init; inline;

var i,j,m,x,y,z:longint;

begin

  readln(n,m);

  for i:=1 to n do read(c[i]);

  for i:=1 to m do

  begin

   
readln(x,y,z);

    inc(x);
inc(y);

    for j:=z to
100 do

    begin

     
ins(j*n+x,(j-z)*n+y,0);

     
ins(j*n+y,(j-z)*n+x,0);

    end;

  end;

  for i:=1 to n do

    for j:=1 to
100 do

     
ins((j-1)*n+i,j*n+i,c[i]);

end;

//=========================================================================

procedure swap(x:longint); inline;

var tt:longint;

begin

  tt:=pi[heap[x]]; pi[heap[x]]:=pi[heap[x shr 1]];
pi[heap[x shr 1]]:=tt;

  tt:=heap[x]; heap[x]:=heap[x shr 1]; heap[x shr
1]:=tt;

end;

//=========================================================================

procedure update(x:longint); inline;

begin

  while x>1 do

    if
dist[heap[x]]<dist[heap[x shr 1]] then

    begin

     
swap(x);

     
x:=x shr 1;

    end else
break;

end;

//=========================================================================

procedure insert(x:longint); inline;

begin

  inc(tot); heap[tot]:=x; pi[x]:=tot;

  update(tot);

end;

//=========================================================================

procedure del; inline;

var i,g,h:longint;

begin

  pi[heap[tot]]:=0; heap[1]:=heap[tot]; dec(tot);
i:=1;

  while i<tot do

  begin

    g:=i shl 1;
h:=i shl 1+1;

    if
(g<=tot) and
(dist[heap[i]]>dist[heap[g]]) then

    begin

     
if (h<=tot) and
(dist[heap[g]]>dist[heap[h]]) then

     
begin

       
swap(h);

       
i:=h;

     
end else

     
begin

       
swap(g);

       
i:=g;

     
end;

    end
else

    if
(h<=tot) and
(dist[heap[i]]>dist[heap[h]]) then

    begin

     
swap(h);

     
i:=h;

    end else
break;

  end;

end;

//=========================================================================

procedure dij_heap; inline;

var i,j,u,v,ans:longint;

begin

  for i:=0 to capa do

    for j:=1 to
n do

    begin

     
dist[i*n+j]:=maxn;

     
pi[i*n+j]:=0;

    end;

  heap[1]:=s; tot:=1; pi[s]:=1; dist[s]:=0;

  while tot>0 do

  begin

    u:=heap[1];
pi[u]:=0; del; i:=en[u];

    while
i<>0 do

    begin
v:=line[i];

     
if v<=lim then

       
if dist[u]+g[i]<dist[v] then

       
begin

         
dist[v]:=dist[u]+g[i];

         
if pi[v]=0 then insert(v) else

           
update(pi[v]);

       
end;

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: