bzoj1295

考虑到这道题n,m都很小,我们考虑先穷举起点i

下面我们要做的是找出移走k个障碍后,点i所能到的最大距离

我们可以把这个问题转化为判定性问题

对于一对点i,j,如果他们之间存在一条路径,障碍数(包括起点终点)小于k,那么这两个点的点间距就是可行间距

也就是说,我们对于每个起点,我们只要做一遍最短路径,然后穷举找到最大可行间距即可(因为图的边数较少)

  1 const dx:array[1..4] of integer=(0,0,-1,1);
  2       dy:array[1..4] of integer=(1,-1,0,0);
  3 type node=record
  4        point,len,next:longint;
  5      end;
  6 
  7 var a,num:array[0..40,0..40] of longint;
  8     p,d:array[0..1010] of longint;
  9     edge:array[0..50010] of node;
 10     q:array[0..100010] of longint;
 11     v:array[0..1010] of boolean;
 12     t,h,i,j,k,n,m,x,y:longint;
 13     ans:double;
 14     s:string;
 15 
 16 function max(a,b:double):double;
 17   begin
 18     if a>b then exit(a) else exit(b);
 19   end;
 20 
 21 function calc(x1,y1,x2,y2:longint):double;
 22   begin
 23     exit(sqrt(sqr(x1-x2)+sqr(y1-y2)));
 24   end;
 25 
 26 procedure add(x,y,c:longint);
 27   begin
 28     inc(h);
 29     edge[h].point:=y;
 30     edge[h].len:=c;
 31     edge[h].next:=p[x];
 32     p[x]:=h;
 33   end;
 34 
 35 procedure spfa(st:longint);
 36   var f,r,x,y,i:longint;
 37   begin
 38     f:=1;
 39     r:=1;
 40     q[1]:=st;
 41     while f<=r do
 42     begin
 43       x:=q[f];
 44       v[x]:=false;
 45       i:=p[x];
 46       while i<>-1 do
 47       begin
 48         y:=edge[i].point;
 49         if d[y]>d[x]+edge[i].len then
 50         begin
 51           d[y]:=d[x]+edge[i].len;
 52           if not v[y] then
 53           begin
 54             inc(r);
 55             q[r]:=y;
 56             v[y]:=true;
 57           end;
 58         end;
 59         i:=edge[i].next;
 60       end;
 61       inc(f);
 62     end;
 63   end;
 64 
 65 begin
 66   fillchar(p,sizeof(p),255);
 67   readln(n,m,t);
 68   for i:=1 to n do
 69   begin
 70     readln(s);
 71     for j:=1 to m do
 72     begin
 73       a[i,j]:=ord(s[j])-48;
 74       inc(k);
 75       num[i,j]:=k;
 76     end;
 77   end;
 78   for i:=1 to n do
 79     for j:=1 to m do
 80       for k:=1 to 4 do
 81       begin
 82         x:=i+dx[k];
 83         y:=j+dy[k];
 84         if num[x,y]>0 then add(num[i,j],num[x,y],a[x,y])
 85       end;
 86 
 87   for i:=1 to n do
 88     for j:=1 to m do
 89     begin
 90       fillchar(v,sizeof(v),false);
 91       v[num[i,j]]:=true;
 92       for k:=1 to n*m do
 93         d[k]:=10000;
 94       d[num[i,j]]:=a[i,j];
 95       spfa(num[i,j]);
 96       for k:=1 to n*m do
 97         if d[k]<=t then
 98           ans:=max(ans,calc(i,j,(k-1) div m+1,(k-1) mod m+1));
 99     end;
100   writeln(ans:0:6);
101 end.
View Code
原文地址:https://www.cnblogs.com/phile/p/4473180.html