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.