Analysis
本题是一道图论题,可用类似于dijkstra算法的思想来解决。设d[i]为i到起点的最小值,初始值d[u]=0其余为INFINITY,每次选取最小的d[i]进行更新。题目来源是IOI99。
Accepted Code
var
rmn,ini,tb,tp,d:array[0..300] of longint;
vis:array[0..300] of boolean;
path,w:array[0..300,0..300] of longint;
u,v,n,m,i,j,a,b,t:longint;
ch:char;
function checkcolor(a,b,t:longint):boolean;
var
colora,colorb,tmp:longint;
begin
if rmn[a]>t then
colora:=ini[a]
else
begin
tmp:=t-rmn[a];
while tmp>=tb[a]+tp[a] do
tmp:=tmp-tb[a]-tp[a];
if ini[a]=0 then
if tp[a]>tmp then
colora:=1
else
colora:=0
else
if tb[a]>tmp then
colora:=0
else
colora:=1;
end;
if rmn[b]>t then
colorb:=ini[b]
else
begin
tmp:=t-rmn[b];
while tmp>=tb[b]+tp[b] do
tmp:=tmp-tb[b]-tp[b];
if ini[b]=0 then
if tp[b]>tmp then
colorb:=1
else
colorb:=0
else
if tb[b]>tmp then
colorb:=0
else
colorb:=1;
end;
if colora=colorb then
checkcolor:=true
else
checkcolor:=false;
end;
function next_time(a,b,t:longint):longint;
var
change_time_a,change_time_b:longint;
begin
change_time_a:=rmn[a];
while change_time_a+tb[a]+tp[a]<t do
change_time_a:=change_time_a+tb[a]+tp[a];
if change_time_a<t then
if ini[a]=0 then
if tp[a]+change_time_a>=t then
change_time_a:=tp[a]+change_time_a
else
change_time_a:=tb[a]+tp[a]+change_time_a
else
if tb[a]+change_time_a>=t then
change_time_a:=tb[a]+change_time_a
else
change_time_a:=tb[a]+tp[a]+change_time_a;
change_time_b:=rmn[b];
while change_time_b+tb[b]+tp[b]<t do
change_time_b:=change_time_b+tb[b]+tp[b];
if change_time_b<t then
if ini[b]=0 then
if tp[b]+change_time_b>=t then
change_time_b:=tp[b]+change_time_b
else
change_time_b:=tb[b]+tp[b]+change_time_b
else
if tb[b]+change_time_b>=t then
change_time_b:=tb[b]+change_time_b
else
change_time_b:=tb[b]+tp[b]+change_time_b;
if change_time_a>change_time_b then
next_time:=change_time_b
else
next_time:=change_time_a;
end;
function time(a,b:longint):longint;
var
t:longint;
begin
if checkcolor(a,b,d[a]) then
begin
time:=d[a]+w[a,b];
exit;
end;
t:=next_time(a,b,d[a]+1);
if checkcolor(a,b,t) then
begin
time:=t+w[a,b];
exit;
end;
t:=next_time(a,b,t+1);
if checkcolor(a,b,t) then
begin
time:=t+w[a,b];
exit;
end;
time:=maxlongint;
exit;
end;
procedure fresh(t:longint);
var
i:longint;
begin
for i:=1 to n do
if not vis[i] and (w[t,i]<maxlongint) and (d[i]>time(t,i)) then
begin
d[i]:=time(t,i);
for j:=1 to path[t,0] do
path[i,j]:=path[t,j];
path[i,0]:=path[t,0]+1;
path[i,path[i,0]]:=i;
end;
end;
procedure dijkstra;
var
i,j,min:longint;
begin
fillchar(path,sizeof(path),0);
fillchar(vis,sizeof(vis),false);
path[u,0]:=1;
path[u,1]:=u;
for i:=1 to n do
d[i]:=maxlongint;
d[u]:=0;
d[0]:=maxlongint;
for i:=1 to n do
begin
min:=0;
for j:=1 to n do
if (d[j]<=d[min]) and not vis[j] then
min:=j;
if d[min]=maxlongint then
break;
vis[min]:=true;
fresh(min);
end;
end;
begin
readln(u,v);
readln(n,m);
for i:=1 to n do
begin
read(ch);
if ch='B' then
ini[i]:=0
else
ini[i]:=1;
readln(rmn[i],tb[i],tp[i]);
end;
for i:=1 to n do
for j:=1 to n do
if i=j then
w[i,j]:=0
else
w[i,j]:=maxlongint;
for i:=1 to m do
begin
readln(a,b,t);
if w[a,b]>t then
begin
w[a,b]:=t;
w[b,a]:=t;
end;
end;
dijkstra;
if d[v]=maxlongint then
writeln(0)
else
begin
writeln(d[v]);
for i:=1 to path[v,0]-1 do
write(path[v,i],' ');
writeln(path[v,path[v,0]]);
end;
end.