noip2001-car的行车路线 2008.11.5
算法:把一个个机场当成一个个点,来进行floyd,只不过是要先分类算一下权值
心得:不要被表象迷惑,要深入剖析,找到数学模型。
本以为这是一道有多么难的题,但是,找到了本质,却发现,真是太简单了!
var
g:array[0..500,0..500] of real;
x,y:array[0..500] of longint;
s:array[1..3] of longint;
n,a,b,nn:longint;
min:real;
f1,f2:text;
procedure swap(var a,b:longint);
var
tmp:longint;
begin
tmp:=a; a:=b; b:=tmp;
end;
procedure floyd;
var
i,j,k:longint;
begin
for k:=1 to 4*n do //floyd算法
for i:=1 to 4*n do
for j:=1 to 4*n do
if g[i,k]+g[k,j]<g[i,j] then
g[i,j]:=g[i,k]+g[k,j];
min:=maxlongint;
for i:=1 to 4 do //枚举16条路径,取最小
for j:=1 to 4 do
if g[(a-1)*4+i,(b-1)*4+j]<min then
min:=g[(a-1)*4+i,(b-1)*4+j];
writeln(f2,min:0:2);
end;
procedure init;
var
ii,i,j,k,l,t,ta:longint;
begin
assign(f1,'cardlxlx.in');reset(f1);
assign(f2,'cardlxlx.out');rewrite(F2);
read(f1,nn);
for ii:=1 to nn do
begin
readln(f1,n,ta,a,b);
for i:=1 to 4*n do
for j:=1 to 4*n do
g[i,j]:=maxlongint;
for i:=1 to n do
begin
for j:=1 to 3 do read(f1,x[j],y[j]); readln(f1,t);
s[3]:=sqr(x[1]-x[2])+sqr(y[1]-y[2]);
s[1]:=sqr(x[2]-x[3])+sqr(y[2]-y[3]);
s[2]:=sqr(x[3]-x[1])+sqr(y[3]-y[1]);
if s[3]=s[1]+s[2] then begin swap(x[1],x[3]); swap(y[1],y[3]); end else
if s[2]=s[1]+s[3] then begin swap(x[1],x[2]); swap(y[1],y[2]); end; //勾股定理找出直角
x[4]:=x[2]+x[3]-x[1]; y[4]:=y[2]+y[3]-y[1]; //向量加法求第四个点
for j:=1 to 4 do begin x[i*4+j]:=x[j]; y[i*4+j]:=y[j]; end;
for j:=1 to 4 do //同一城市的边的权值
for l:=j to 4 do
begin
g[(i-1)*4+j,(i-1)*4+l]:=sqrt(sqr(x[j]-x[l])+sqr(y[j]-y[l]))*t;
g[(i-1)*4+l,(i-1)*4+j]:=g[(i-1)*4+j,(i-1)*4+l];
end;
for j:=1 to i-1 do //不同城市的边的权值
for l:=1 to 4 do
for k:=1 to 4 do
begin
g[(i-1)*4+l,(j-1)*4+k]:=sqrt(sqr(x[i*4+l]-x[j*4+k])+sqr(y[i*4+l]-y[j*4+k]))*ta;
g[(j-1)*4+k,(i-1)*4+l]:=g[(i-1)*4+l,(j-1)*4+k];
end;
end;
floyd;
end;
end;
begin
init;
close(f1);close(f2);
end.