【BZOJ1070】修车(费用流)

题意:同一时刻有N位车主带着他们的爱车来到了汽车维修中心。

维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。

现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。

说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)

题意:RYZ作业

费用流经典模型之一

对于一次修车我们有三个属性,车的编号,人的编号,以及它是这个人倒数第几个修的车

为什么不是正数第几个?因为不知道每个人各自要修多少辆,这样就无法统计它让后面的车主等待的时间

而对于倒数第K修的车,它让后面以及当前的的车主多等待了a[i,j]*k的时间

将人裂点,(i,j)表示这是第i个人修的倒数第j辆车

源点连车,容量为1,费用为0

车连人裂的点,容量为1,费用为a[i,j]*k

人裂的点连汇点,容量为1,费用为0

 

  1 var head,vet,next,len1,len2,dis,fan:array[1..200000]of longint;
  2     inq:array[1..200000]of boolean;
  3     pre:array[1..200000,1..2]of longint;
  4     q:array[0..3000]of longint;
  5     a,num:array[1..60,1..60]of longint;
  6     n,m,i,j,k,tot,src,source,s:longint;
  7     ans:double;
  8 
  9 function min(x,y:longint):longint;
 10 begin
 11  if x<y then exit(x);
 12  exit(y);
 13 end;
 14 
 15 procedure add(a,b,c,d:longint);
 16 begin
 17  //writeln(a,' ',b,' ',c,' ',d);
 18  inc(tot);
 19  next[tot]:=head[a];
 20  vet[tot]:=b;
 21  len1[tot]:=c;
 22  len2[tot]:=d;
 23  head[a]:=tot;
 24 
 25  inc(tot);
 26  next[tot]:=head[b];
 27  vet[tot]:=a;
 28  len1[tot]:=0;
 29  len2[tot]:=-d;
 30  head[b]:=tot;
 31 end;
 32 
 33 
 34 function spfa:boolean;
 35 var u,e,v,i,t,w:longint;
 36 begin
 37  for i:=1 to s do
 38  begin
 39   dis[i]:=maxlongint>>1;
 40   inq[i]:=false;
 41  end;
 42  t:=0; w:=1; q[1]:=source; dis[source]:=0; inq[source]:=true;
 43  while t<w do
 44  begin
 45   inc(t); u:=q[t mod 3000];
 46   inq[u]:=false;
 47   e:=head[u];
 48   while e<>0 do
 49   begin
 50    v:=vet[e];
 51    if (len1[e]>0)and(dis[u]+len2[e]<dis[v]) then
 52    begin
 53     pre[v,1]:=u;
 54     pre[v,2]:=e;
 55     dis[v]:=dis[u]+len2[e];
 56     if not inq[v] then
 57     begin
 58      inc(w); q[w mod 3000]:=v; inq[v]:=true;
 59     end;
 60    end;
 61    e:=next[e];
 62   end;
 63  end;
 64  if dis[src]=maxlongint>>1 then exit(false);
 65  exit(true);
 66 end;
 67 
 68 procedure mcf;
 69 var k,e,t:longint;
 70 begin
 71  k:=src; t:=maxlongint;
 72  while k<>source do
 73  begin
 74   t:=min(t,len1[pre[k,2]]);
 75   k:=pre[k,1];
 76  end;
 77  k:=src;
 78  while k<>source do
 79  begin
 80   e:=pre[k,2];
 81   len1[e]:=len1[e]-t;
 82   len1[fan[e]]:=len1[fan[e]]+t;
 83   ans:=ans+t*len2[e];
 84   k:=pre[k,1];
 85  end;
 86 end;
 87 
 88 begin
 89  assign(input,'bzoj1070.in'); reset(input);
 90  assign(output,'bzoj1070.out'); rewrite(output);
 91  readln(m,n);
 92  for i:=1 to 200000 do
 93   if i and 1=1 then fan[i]:=i+1
 94    else fan[i]:=i-1;
 95  for i:=1 to n do
 96   for j:=1 to m do read(a[i,j]);
 97  s:=n;
 98  for i:=1 to m do
 99   for j:=1 to n do
100   begin
101    inc(s); num[i,j]:=s;
102   end;
103  inc(s); source:=s;
104  inc(s); src:=s;
105  for i:=1 to n do add(source,i,1,0);
106  for i:=1 to n do
107   for j:=1 to m do
108    for k:=1 to n do add(i,num[j,k],1,a[i,j]*k);
109  for i:=1 to m do
110   for j:=1 to n do add(num[i,j],src,1,0);
111  while spfa do mcf;
112  writeln(ans/n:0:2);
113  close(input);
114  close(output);
115 end.

 

posted on 2017-03-05 20:02  myx12345  阅读(103)  评论(0编辑  收藏  举报

导航