bzoj 1579 [Usaco2009 Feb]Revampi…
来源:互联网 发布:移动进销存软件 编辑:程序博客网 时间:2024/05/21 00:54
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上的代码吧、、
ACCODE
{$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 to100 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 to100 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 shr1]:=tt;
end;
//=========================================================================
procedure update(x:longint); inline;
begin
while x>1 do
ifdist[heap[x]]<dist[heap[x shr 1]] then
begin
swap(x);
x:=x shr 1;
end elsebreak;
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;
endelse
if(h<=tot) and(dist[heap[i]]>dist[heap[h]]) then
begin
swap(h);
i:=h;
end elsebreak;
end;
end;
//=========================================================================
procedure dij_heap; inline;
var i,j,u,v,ans:longint;
begin
for i:=0 to capa do
for j:=1 ton 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];
whilei<>0 do
beginv:=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;
http://poj.org/problem?id=3635
两题实在长,我就不贴了。
这两题的做法都是一样的,在dij的时候多加一维分别表示当前剩余的更新次数(poj里面是余油量)。
很多人都是开个二维数组搞的,但是今天看到一个拆点的做法相当神奇~~原文地址如下:
http://hi.baidu.com/lrc2222/blog/item/e40177f76c37b338720eecc7
大意就是把n个点分成k层,k即原方法中的第二位,然后把0长度的边连在不同的层之间表示更新路径使时间为0,相同层里面的点连原时间长度的边表示不更新路径直接走。最后在每一层里面的终点值里取个最优的输出。
对于poj里面的那题所连的边都是在不同层之间的。向较上一层的自己连一条长度为一单位油价的边表示加油,向下d层的j点连一条权值为0的边表示有一条长度为d的路与j连接。
这样建完图就是裸裸的dij+heap了~~~
不过poj上的那题一早上总是超时。。。怎么卡时都不过。。。后来看标程发现一个露加的优化:
当第0层的终点有值的时候就退出。
因为用的是dij,正确性显而易见。。。
但是bzoj上的那道题就不能用这个优化了。。。有可能k次更新不许要都用完就已经走到了。。。
这里就贴一个poj上的代码吧、、
ACCODE
{$inline on}
program pku_3635;
const maxn=99999999;
var line,next,g:array[1..2100000] of longint;
//=========================================================================
procedure ins(x,y,z:longint); inline;
begin
end;
//=========================================================================
procedure init; inline;
var i,j,m,x,y,z:longint;
begin
end;
//=========================================================================
procedure swap(x:longint); inline;
var tt:longint;
begin
end;
//=========================================================================
procedure update(x:longint); inline;
begin
end;
//=========================================================================
procedure insert(x:longint); inline;
begin
end;
//=========================================================================
procedure del; inline;
var i,g,h:longint;
begin
end;
//=========================================================================
procedure dij_heap; inline;
var i,j,u,v,ans:longint;
begin