Car的旅行路线(NOIP2001)

deadrain 发表于 2007-08-14 23:41:55

主要是构造图,如果不知道其他判定直角的方法,也可以用勾股,算出第4个点的坐标。
因为出发和到达城市中的机场可以任意选取,所以这两个城市内的高速铁路单位里程的价格可以都设为0,其他的各点间的权值即为原本的飞机的价格或铁路的价格。
这些线都连好之后再用floyed算出出发城市各点到到达城市各点的最小距离,最后再统计一下这些最小距离中的最小者,即为解。

CODE:
------------------------------------------

program p1119;
type arr=record
          x,y:array[1..4] of integer;
          car:integer;
         end;
var
 city:array[1..100] of arr;
 w:array[1..400,1..400] of extended;
 n,fly,car,a,b:longint;
 i,j:integer;
 min:extended;

procedure init;
var
 i,j,k,swap:integer;
 d12,d23,d13:extended;
begin
 readln(n,fly,a,b);
 if a=b then begin writeln('0.00');halt;end;
 for i:=1 to n do
   with city[i] do
    begin
     for j:=1 to 3 do read(x[j],y[j]);
     readln(car);if (i=a) or (i=b) then car:=0;
     for j:=1 to 2 do
      for k:=j+1 to 3 do
       if x[j]>x[k] then begin
          swap:=x[j];x[j]:=x[k];x[k]:=swap;
          swap:=y[j];y[j]:=y[k];y[k]:=swap;
       end;
     d12:=sqr(x[1]-x[2])+sqr(y[1]-y[2]);
     d23:=sqr(x[2]-x[3])+sqr(y[2]-y[3]);
     d13:=sqr(x[1]-x[3])+sqr(y[1]-y[3]);
     if d12+d13=d23 then begin
        x[4]:=x[2]+x[3]-x[1];
        y[4]:=y[2]+y[3]-y[1];
     end
     else
     if d12+d23=d13 then begin
        x[4]:=x[1]+x[3]-x[2];
        y[4]:=y[1]+y[3]-y[2];
     end
     else
     if d13+d23=d12 then begin
        x[4]:=x[1]+x[2]-x[3];
        y[4]:=y[1]+y[2]-y[3];
     end;
  end;
end;
procedure prepare;
 var
  i,j,k,l:integer;
 begin
  for i:=1 to n do
   with city[i] do
    begin
     for j:=1 to 3 do
      for k:=j+1 to 4 do
       begin
           w[4*i-4+j][4*i-4+k]:=sqrt(sqr(x[j]-x[k])+sqr(y[j]-y[k]))*car;
           w[4*i-4+k][4*i-4+j]:=w[4*i-4+j][4*i-4+k];
       end;
    end;
  for i:=1 to n do
   for j:=1 to n do
    if i<>j then begin
       for k:=1 to 4 do
        for l:=1 to 4 do
         w[i*4-4+k][j*4-4+l]:=sqrt(sqr(city[i].x[k]-city[j].x[l])+sqr(city[i].y[k]-city[j].y[l]))*fly;
    end;
end;
procedure floyed;
var
 i,j,k:integer;
begin
 for k:=1 to n*4 do
  for i:=1 to n*4 do
   if i<>k then
    for j:=1 to n*4 do
     if (i<>j) and (j<>k) then
        if w[i][k]+w[k][j]<w[i][j] then w[i][j]:=w[i][k]+w[k][j];
end;
begin
 init;
 prepare;
 floyed;
 min:=1000000;
 for i:=1 to 4 do
  for j:=1 to 4 do
   if w[a*4-4+i][b*4-4+j]<min then min:=w[a*4-4+i][b*4-4+j];
 writeln(min:0:2);
end.

关键词(Tag): noip vijos


收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定