【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

 var head,vet,next,len1,len2,dis,fan:array[..]of longint;
inq:array[..]of boolean;
pre:array[..,..]of longint;
q:array[..]of longint;
a,num:array[..,..]of longint;
n,m,i,j,k,tot,src,source,s:longint;
ans:double; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure add(a,b,c,d:longint);
begin
//writeln(a,' ',b,' ',c,' ',d);
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len1[tot]:=c;
len2[tot]:=d;
head[a]:=tot; inc(tot);
next[tot]:=head[b];
vet[tot]:=a;
len1[tot]:=;
len2[tot]:=-d;
head[b]:=tot;
end; function spfa:boolean;
var u,e,v,i,t,w:longint;
begin
for i:= to s do
begin
dis[i]:=maxlongint>>;
inq[i]:=false;
end;
t:=; w:=; q[]:=source; dis[source]:=; inq[source]:=true;
while t<w do
begin
inc(t); u:=q[t mod ];
inq[u]:=false;
e:=head[u];
while e<> do
begin
v:=vet[e];
if (len1[e]>)and(dis[u]+len2[e]<dis[v]) then
begin
pre[v,]:=u;
pre[v,]:=e;
dis[v]:=dis[u]+len2[e];
if not inq[v] then
begin
inc(w); q[w mod ]:=v; inq[v]:=true;
end;
end;
e:=next[e];
end;
end;
if dis[src]=maxlongint>> then exit(false);
exit(true);
end; procedure mcf;
var k,e,t:longint;
begin
k:=src; t:=maxlongint;
while k<>source do
begin
t:=min(t,len1[pre[k,]]);
k:=pre[k,];
end;
k:=src;
while k<>source do
begin
e:=pre[k,];
len1[e]:=len1[e]-t;
len1[fan[e]]:=len1[fan[e]]+t;
ans:=ans+t*len2[e];
k:=pre[k,];
end;
end; begin
assign(input,'bzoj1070.in'); reset(input);
assign(output,'bzoj1070.out'); rewrite(output);
readln(m,n);
for i:= to do
if i and = then fan[i]:=i+
else fan[i]:=i-;
for i:= to n do
for j:= to m do read(a[i,j]);
s:=n;
for i:= to m do
for j:= to n do
begin
inc(s); num[i,j]:=s;
end;
inc(s); source:=s;
inc(s); src:=s;
for i:= to n do add(source,i,,);
for i:= to n do
for j:= to m do
for k:= to n do add(i,num[j,k],,a[i,j]*k);
for i:= to m do
for j:= to n do add(num[i,j],src,,);
while spfa do mcf;
writeln(ans/n::);
close(input);
close(output);
end.
上一篇:Jmeter+JDK的安装学习笔记


下一篇:git工具使用说明