hdu 1245 Saving James Bond dij

<span style="font-size:18px;">题目大意</span>

有一个100*100的正方形湖,湖中间有一个直径为15的圆形小岛;

有n个点随机分布在这个正方形中;

一个人要从小岛上跳出湖外,可以跳跃在这些点上;

人每一步能跳的最大距离为d;

求能跳出湖外所需的最小的跳跃距离和步数;

 

分析

首先计算每个坐标两两间的距离;

然后找出所有能从小岛上一步跳到的点存入数组s中;

然后找出所有能一步跳出湖外的点存入数组t中;

设置两个虚拟的顶点s和t;

用s与数组s中的所有顶点相连;

用t与数组t中的所有顶点相连;

即此题可以转换成求s到t的最短路径;

 

注意

在建图的过程中,如果两个顶点之间的距离大于d了;

即两个顶点之间无法一步到达,所以此时将权值赋为无穷大;

此题很是有点卡精度,下面的pascal始终过不了。


代码

const
  eps=1e-4;

var
  f:array[1..200,1..200] of double;
  a:array[1..200,1..2] of longint;
  v,c:array[0..200] of longint;
  d:array[0..200] of double;
  i,j,l:longint;
  x,y:longint;
  x1,y1,k,q:double;
  n,m:longint;
  ans,max:longint;

procedure a1;
var
  i,j:longint;
begin
  for i:=1 to 200 do
    for j:=1 to 200 do
      f[i,j]:=maxlongint;
  for i:=0 to 200 do
    d[i]:=maxlongint;
end;

begin
  while not eof do
  begin
  readln(n,q);
  a1;
  fillchar(a,sizeof(a),0);
  fillchar(v,sizeof(v),0);
  fillchar(c,sizeof(c),0);
  y1:=d[1];
  j:=0;
  for i:=1 to n do
    begin
      readln(x,y);
      if sqrt(sqr(x)+sqr(y))-7.5<=eps
        then
          continue;
      j:=j+1;
      a[j,1]:=x; a[j,2]:=y;
    end;
  n:=j;
  if q-42.50>=eps
    then
      begin
        writeln(42.5:0:2,' ',1);
        continue;
      end;
  for i:=1 to n do
    for j:=1 to n do
      begin
        f[i,j]:=sqrt(sqr(a[i,1]-a[j,1])+sqr(a[i,2]-a[j,2]));
        if f[i,j]-q>eps
          then
            f[i,j]:=maxlongint;
      end;
  for i:=1 to n do
    begin
      x1:=sqrt(sqr(a[i,1])+sqr(a[i,2]))-7.5;
      if x1-q>eps
        then f[i,n+1]:=maxlongint
        else f[i,n+1]:=x1;
      f[n+1,i]:=f[i,n+1];
      if abs(50-a[i,1])>abs(50-a[i,2])
        then f[i,n+2]:=abs(50-a[i,2])
        else f[i,n+2]:=abs(50-a[i,1]);
      if f[i,n+2]-q>eps
        then f[i,n+2]:=maxlongint;
      f[n+2,i]:=f[i,n+2];
    end;
  n:=n+2;
  d[n-1]:=0;
  c[n-1]:=0;
  for i:=1 to n do
    begin
      k:=maxlongint;
      l:=0;
      for j:=1 to n do
        if (v[j]=0) and (d[j]-k<eps)
          then
            begin
              k:=d[j];
              l:=j;
            end;
      v[l]:=1;
      if l=0 then break;
      for j:=1 to n do
        if (d[j]-d[l]-f[l,j]>eps) or ((d[j]-d[l]-f[l,j]<=eps) and (c[l]+1<c[j]))
          then
            begin
              d[j]:=d[l]+f[l,j];
              c[j]:=c[l]+1;
            end;
    end;
  if d[n]=y1 then writeln('can''t be saved')
  else writeln(d[n]:0:2,' ',c[n]);
  end;
end.



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值