最小密度路径(path)
【题目描述】
给出了一张有N个点M条边的加权,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。
【输入格式】
第一行包括2个整数N和M。
以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边。
再下一行有一个整数Q。
以下Q行,每行一个询问X和Y,如题意所诉。
【输出格式】
对于每个询问输出一行,表示该询问的最小密度路径的密度(保留3位小数),如果不存在这么一条路径输出“OMG!”(不含引号)。
【输入样例】
3 3
1 3 5
2 1 6
2 3 6
2
1 3
2 3
【输出样例】
5.000
5.500
【数据规模】
对于60%的数据,有1 ≤ N ≤ 10,1 ≤ M ≤ 100,1 ≤ W≤ 1000,1 ≤ Q ≤ 1000;
对于100%的数据,有1 ≤ N ≤ 50,1 ≤ M ≤ 1000,1 ≤ W ≤ 100000,1 ≤ Q ≤ 100000。
===========================================
改进floyed
==========================
var
n,m:longint;
map:array[1..50,1..50]of longint;
f:array[1..50,1..50,1..50]of longint;
ans:array[1..50,1..50]of extended;
procedure init;
begin
assign(input,'path.in');
assign(output,'path.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
procedure main;
var
a,b,w:longint;
l,i,j,k:longint;
q:longint;
begin
readln(n,m);
fillchar(map,sizeof(map),$7);
fillchar(f,sizeof(f),$7);
for i:=1 to m do
begin
readln(a,b,w);
if w<map[a,b] then map[a,b]:=w;
f[1,a,b]:=map[a,b];
end;
for l:=2 to n do
for k:=1 to n do
for i:=1 to n do
for j:=1 to n do
if f[l,i,j]>f[l-1,i,k]+map[k,j] then f[l,i,j]:=f[l-1,i,k]+map[k,j];
for i:=1 to n do
for j:=1 to n do
ans[i,j]:=maxlongint;
for i:=1 to n do
for j:=1 to n do
for k:=1 to n do
if f[i,j,k]/i<ans[j,k] then ans[j,k]:=f[i,j,k]/i;
readln(q);
for i:=1 to q do
begin
read(a,b);
if ans[a,b]<100000 then writeln(ans[a,b]:0:3)
else writeln('OMG!');
end;
end;
begin
init;
main;
terminate;
end.