noip2001-car的行车路线 2008.11.5

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.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值