Description
小澳最喜欢的歌曲就是《葫芦娃》。
一日表演唱歌,他尽了洪荒之力,唱响心中圣歌。
随之,小澳进入了葫芦世界。
葫芦世界有n个葫芦,标号为1~ n。n个葫芦由m条藤连接,每条藤连接了两个葫芦,这些藤构成了一张有向无环图。小澳爬过每条藤都会消耗一定的能量。
小澳站在1号葫芦上(你可以认为葫芦非常大,可以承受小澳的体重),他想沿着藤爬到n号葫芦上,其中每个葫芦只经过一次。
小澳找到一条路径,使得消耗的能量与经过的葫芦数的比值最小。
Input
输入文件名为calabash.in。
输入文件第一行两个正整数n,m,分别表示葫芦的个数和藤数。
接下来m行,每行三个正整数u,v,w,描述一条藤,表示这条藤由u连向v,小澳爬过这条藤需要消耗w点能量。
Output
输出文件名为calabash.out。
一行一个实数,表示答案(绝对误差不超过 10^-3)。
分析
先加入一个新点0,从0到1连一条长度为0的边,那么问题就穿换成了路径长度/边数最小。
设答案为ans,可得答案路径:
(w[1]+w[2]+w[3]...w[n])/n=ans
变式:
w[1]+w[2]+w[3]...w[n]=ans∗n
继续:
(w[1]−ans)+(w[2]−ans)+(w[3]−ans)...(w[n]−ans)=0
那么我们就二分一个答案ans,然后把每条边的权值减去ans,若1到n的最短路=0,则ans就是答案。
如果1到n的最短路>0,则l=mid+1
如果1到n的最短路<0,则r=mid-1
神tm的ssl的int64.。。
代码
const
maxe=50000;
maxv=3000000;
type
arr=record
x,y,next:longint;
w:longint;
end;
var
n,m,s,q:longint;
ls:array[0..maxe] of longint;
a:array[0..maxv] of arr;
f:array[0..maxe] of int64;
v:array[0..maxe] of longint;
d:array[0..maxv] of longint;
i,j,k:longint;
ans:int64;
x,y:longint;
l,r,mid:int64;
max:int64;
function spfa(s,t:longint;mid:int64):int64;
var
i,j,k:longint;
head,tail:longint;
begin
fillchar(f,sizeof(f),$7f);
max:=f[1];
head:=0;
tail:=1;
v[s]:=1;
d[1]:=s;
f[s]:=1;
repeat
head:=head+1;
j:=ls[d[head]];
while j<>0 do
begin
with a[j] do
begin
if f[x]+w-mid<f[y]
then
begin
f[y]:=f[x]+w-mid;
if v[y]=0
then
begin
tail:=tail+1;
d[tail]:=y;
v[y]:=1;
end;
end;
j:=next;
end;
end;
v[d[head]]:=0;
until head=tail;
spfa:=f[t];
end;
begin
readln(n,m);
fillchar(ls,sizeof(ls),0);
for i:=1 to m do
begin
with a[i] do
begin
readln(x,y,w);
w:=w*10000;
next:=ls[x];
ls[x]:=i;
end;
end;
m:=m+1;
a[m].x:=0;
a[m].y:=1;
ls[0]:=m;
ans:=0;
x:=0; y:=n;
l:=0; r:=200000000; mid:=0;
while (l<r) do
begin
mid:=(l+r) div 2;
if spfa(x,y,mid)>=0
then begin
ans:=mid;
l:=mid+1;
end
else
r:=mid-1;
end;
write(ans/10000:0:3);
end.