firefox 最短路spfa 的应用

36 篇文章 0 订阅
35 篇文章 0 订阅
 
 
From 西部314
firefox
 
   

 

 

 

 

描述 Description

 

 

  山火来了,Fox们遇到了前所未有的危机,他们需要马上撤离这个区域。但是居住在离山火区域较远的Fox仍然不知道危险降临。这个时候,前方的Fox要用叫声来提醒其他的Fox。Fox的视野为S米,叫声最远能传到D米之外。山上有p处着火的地点,当着火点在Fox的视野中时,Fox就会发出叫声(进入视野是指Fox与火点距离<=S)。因为山风,声音传播的速度为v米/秒。那么如果要使所有的Fox都得到危险信号,至少需要多长时间?
假设着火点为一个整数坐标,着火点不会移动也不会扩大。Fox听到同伴叫声就会立刻把信号传递下去。

 

 

 

 

 

 

 

输入格式 Input Format

 

 

  第1行两个整数n,p,表示Fox数量和着火点数量
第2行三个整数 S,D,v
第3~p+2行,每行两整数x,y表示着火点坐标
接下来n行每行两个整数x,y表示Fox坐标

 

 

 

 

 

 

 

输出格式 Output Format

 

 

使所有Fox都得到信号所需的最短时间,答案为四舍五入之后的整数。题目保证所有Fox最终都会得到信号,不存在Fox哑嗓子或者被山火烧死的可能。

 

 

 

 

 

 

 

样例输入 Sample Input [复制数据]

 

 

 

 

 

 

 

 

 

样例输出 Sample Output [复制数据]

 

 

 

 

 

 

 

 

 

时间限制 Time Limitation

 

 

各个测试点1s

 

 

 

 

 

 

 

注释 Hint

 

 

对于100%的数据 n<=2000
  p<=10
  s,d,v<=1000
坐标绝对值小于等于10000

 

 

 

 

 

 

 

来源 Source

 

 

来源:Delostik 开学欢乐赛

 

 

var x,y,dx,dy,dui:array[0..2000] of longint;
a:array[0..2000,0..2000] of real;
f:array[0..2000] of real;
b:array[0..2000] of boolean;
n,m,i,j,p,s,d,v,t,w:longint;
sum:real;
function find(x1,x2,y1,y2:longint):real;
begin
 find:=sqrt(sqr(x1-x2)+sqr(y1-y2));
end;
procedure bfs;
var i,j,k,now:longint;
dis:real;
begin
 t:=0;
 while t<w do
  begin
   inc(t); now:=dui[t];
   for i:=1 to n do
    begin
     dis:=find(x[i],x[now],y[i],y[now]);
     if dis<=d then if f[now]+dis<f[i] then
      begin
       f[i]:=f[now]+dis;
       if not b[i] then
        begin
         inc(w); dui[w]:=i; b[i]:=true;
        end;
      end;
    end;
   b[now]:=false;
  end;
end;
begin
 readln(n,p);
 readln(s,d,v);
 for i:=1 to p do
  readln(dx[i],dy[i]);
 for i:=1 to n do
  readln(x[i],y[i]);
 for i:=1 to n do
  for j:=1 to n do
   if i<>j then
    a[i,j]:=find(x[i],x[j],y[i],y[j]);
 w:=0;
 for i:=1 to n do f[i]:=maxlongint div 100;
 fillchar(b,sizeof(b),0);
 for i:=1 to n do
  for j:=1 to p do
   if find(x[i],dx[j],y[i],dy[j])<=s then
    begin
     inc(w); dui[w]:=i; f[i]:=0; b[i]:=true; break;
    end;
 bfs;
 sum:=0;
 for i:=1 to n do
  if f[i]>sum then sum:=f[i];
 writeln(round(sum/v));
end.


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值