您的位置:首页 > 其它

【BZOJ1070】修车(费用流)

2017-03-05 20:02 281 查看

题意:同一时刻有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.

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: