您的位置:首页 > 其它

洛谷 P1462 通往奥格瑞玛的道路

2017-03-24 19:12 423 查看
题目大意:

歪嘴哦想去奥格瑞玛即城市n,如果能到达的话,求在可行的所有路径中,交费最多的一次的
4000
最小值,不能到达输出“AFK”。

题解:

二分查找+spfa+队列:

1.找出城市中最小收费跟最大收费,然后对费用做2分查找。

2.对于二分的费用mid,做spfa,如果i可以到达奥格瑞玛且血量不超过歪嘴哦的血量就向前二分,不然到达就向后二分。

3.如果二分做完了,还不能到达就输出“AFK”,否则输出二分的结果。

var
c,s,t,w,next,list:array [0..100001] of int64;
a,d:array [0..10001] of int64;
v:array [0..10001] of boolean;
min,max,i,n,m,p,q,ans:longint;

function spfa(main:longint):boolean;
var
head,tail,j:longint;
begin
d[1]:=w[1]; for j:=2 to n do d[j]:=maxlongint;
v[1]:=true; for j:=2 to n do v[j]:=false;
head:=0;
tail:=1;
c[1]:=1;
while head<tail do
begin
inc(head);
j:=list[c[head]];
while j>0 do
begin
if (a[t[j]]<=main) and (d[s[j]]+w[j]<d[t[j]])
then begin
d[t[j]]:=d[s[j]]+w[j];
if v[t[j]]=false
then begin
v[t[j]]:=true;
inc(tail);
c[tail]:=t[j];
end;
end;
j:=next[j];
end;
v[c[head]]:=false;
end;
if d
<=p then exit(true);
exit(false);
end;

procedure find(l,r:longint);
var
mid:longint;
begin
if l>=r then
begin
if spfa(l) then writeln(l)
else writeln('AFK');
halt
end;
mid:=(l+r) div 2;
if spfa(mid)
then find(l,mid)
else find(mid+1,r);
end;

begin
readln(n,m,p);
min:=maxlongint; max:=0;
for i:=1 to n do
begin
readln(a[i]);
if a[i]<min then min:=a[i];
if a[i]>max then max:=a[i];
end;
for i:=1 to m do
begin
inc(q);
readln(s[q],t[q],w[q]);
next[q]:=list[s[q]];
list[s[q]]:=q;
inc(q);
s[q]:=t[q-1]; t[q]:=s[q-1]; w[q]:=w[q-1];
next[q]:=list[s[q]];
list[s[q]]:=q;
end;
find(min,max);
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: