1579 泽泽在巴西

来源:互联网 发布:ps淘宝详情页制作步骤 编辑:程序博客网 时间:2024/05/17 09:32

  • 题目
  • 题解
    • 足球流氓判断方法
    • 两点间距离
    • 注意
    • 时间复杂度
  • 代码

题目

比赛开始,泽泽队率先发球。泽泽观察了四周,想怎么才能用最短的时间射门呢?
  射门的时间为距离*2,而传球的时间是距离*1。所以泽泽想找一条用时最少的射门路径,来打败足球流氓。
  足球流氓当然不会袖手旁观,他们会拦截。当泽泽队伍中的传球人、被传球人之间有某足球流氓并且他们在同一直线上时,传球不会成功,即不能这样传球。比如A(1,2)想传球给B(7,8),中间有个足球流氓C(3,4),则他们在同一直线,传球不成功。射门不受足球流氓影响。

题解

枚举所有点之间的路径,如果没有足球流氓就连一条边,边权即两点间距离。

然后SPFA跑一边

足球流氓判断方法

叉积为0,且足球流氓在两点中间

两点间距离

((x1x0)2(y1y0)2)

注意

射门不受足球流氓影响,且时间要*2
放边的数据不要太小,至少200000

时间复杂度

O(n3)

代码

type  rec=record        x,y,ne:longint;        w:real;      end;var  x0,y0,n,mm,i,j,k,l,t:longint;  e:array[1..500000]of rec;  a,b:array[1..500,1..2]of longint;  d:array[1..500]of real;  state,v:array[1..500000]of longint;  ls:array[1..500]of longint;function m(x0,y0,x1,y1,x2,y2:longint):longint;var  x,y,xx,yy:longint;begin  x:=x0;xx:=x1;  if x0<x1 then begin x:=x1;xx:=x0;end;  y:=y0;yy:=y1;  if y0<y1 then begin y:=y1;yy:=y0;end;  if (x2>x)or(x2<xx)or(y2>y)or(y2<yy) then exit(1) else  m:=((x2-x0)*(y1-y0))-((x1-x0)*(y2-y0));end;procedure spfa;var  h,t,x,y,l:longint;  w:real;begin  h:=0;t:=1;state[t]:=1;  d[1]:=0;  while h<t do    begin      inc(h);      l:=ls[state[h]];      while l>0 do        begin          x:=e[l].x;y:=e[l].y;w:=e[l].w;          if d[x]+w<d[y] then            begin              d[y]:=d[x]+w;              if (v[y]=0)and(y<>n+1) then                begin                  inc(t);                  state[t]:=y;                  v[y]:=1;                end;            end;          l:=e[l].ne;        end;      v[state[h]]:=0;    end;end;begin  readln(x0,y0,n,mm);  fillchar(d,sizeof(d),$7f);  for i:=1 to n do    readln(a[i,1],a[i,2]);  for i:=1 to mm do    readln(b[i,1],b[i,2]);  for i:=1 to n do    for j:=1 to n do      if i<>j then        begin          l:=0;          for k:=1 to mm do            if m(a[i,1],a[i,2],a[j,1],a[j,2],b[k,1],b[k,2])=0 then              begin l:=1;break;end;          if l=0 then            begin              inc(t);              e[t].x:=i;e[t].y:=j;              e[t].w:=sqrt(sqr(a[i,1]-a[j,1])+sqr(a[i,2]-a[j,2]));              e[t].ne:=ls[i];              ls[i]:=t;            end;        end;  for i:=1 to n do    begin      inc(t);      e[t].x:=i;e[t].y:=n+1;      e[t].w:=sqrt(sqr(a[i,1]-x0)+sqr(a[i,2]-y0))*2;      e[t].ne:=ls[i];      ls[i]:=t;    end;  spfa;  writeln(d[n+1]:0:0);end.
2 0