1070: [SCOI2007]修车 - BZOJ

Description

同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
Input

第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。
Output

最小平均等待时间,答案精确到小数点后2位。
Sample Input
2 2
3 2
1 4
Sample Output
1.50

HINT

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

 

费用流建图,把m个人每个人拆成n个点,表示的是第m个人倒数第i个修这个车,那么费用就是i*时间

没想到zkw费用流模板打错了

在dfs过程里

我是这么写的

 1 function dfs(x,flow:longint):longint;

 2 var

 3         i,d,min:longint;

 4 begin

 5         flag[x]:=time;

 6         if x=t then

 7         begin

 8           inc(ans,flow*dis[t]);

 9           exit(flow);

10         end;

11         i:=first[x];

12         dfs:=0;

13         while i<>0 do

14           begin

15             d:=dis[x]+w[i]-dis[last[i]];

16             min:=flow;

17             if min>liu[i] then min:=liu[i];

18             if (liu[i]>0) and (d<f[last[i]]) then f[last[i]]:=d;

19             if (d=0) and (flag[last[i]]<>time) and (min>0) then

20             begin

21               d:=dfs(last[i],min);

22               dec(flow,d);

23               inc(dfs,d);

24               inc(liu[i xor 1],d);

25               dec(liu[i],d);

26             end;

27             if flow=0 then break;

28             i:=next[i];

29           end;

30 end;

但是应该这么写

 1 function dfs(x,flow:longint):longint;

 2 var

 3         i,d,min:longint;

 4 begin

 5         if x=t then

 6         begin

 7           inc(ans,flow*dis[t]);

 8           exit(flow);

 9         end;

10         i:=first[x];

11         flag[x]:=time;

12         dfs:=0;

13         while i<>0 do

14           begin

15             d:=dis[x]+w[i]-dis[last[i]];

16             min:=flow;

17             if min>liu[i] then min:=liu[i];

18             if (liu[i]>0) and (d<f[last[i]]) then f[last[i]]:=d;

19             if (d=0) and (flag[last[i]]<>time) and (min>0) then

20             begin

21               d:=dfs(last[i],min);

22               dec(flow,d);

23               inc(dfs,d);

24               inc(liu[i xor 1],d);

25               dec(liu[i],d);

26             end;

27             if flow=0 then break;

28             i:=next[i];

29           end;

30 end;

应该先判断是否走到了汇点,再做标记,如果不这样的话,就无法多路增广了,即只能到达汇点一次,然后他会立即增加dis,这个时候dis就是错的了(因为较小的那个dis还没有增广完全)

对于其他的点,都是增广到不能再增广,所以没有问题,只要访问一次就行了(应该是这样的吧)

写了几遍了,连这个都没有发现,唉~~~~

  1 const

  2         maxn=62;

  3         maxm=10;

  4         inf=100000000;

  5 var

  6         n,m,tot,s,t,ans,time:longint;

  7         first,f,dis,flag:array[0..maxn*maxm]of longint;

  8         last,next,w,liu:array[0..maxn*maxn*maxm*maxm]of longint;

  9  

 10 procedure insert(x,y,f,ww:longint);

 11 begin

 12         inc(tot);

 13         last[tot]:=y;

 14         next[tot]:=first[x];

 15         first[x]:=tot;

 16         w[tot]:=ww;

 17         liu[tot]:=f;

 18 end;

 19  

 20 procedure init;

 21 var

 22         i,j,k,x:longint;

 23 begin

 24         read(m,n);

 25         tot:=1;

 26         s:=0;

 27         t:=n*m+n+1;

 28         for i:=1 to n do

 29           for j:=1 to m do

 30             begin

 31               read(x);

 32               for k:=1 to n do

 33                 begin

 34                   insert((j-1)*n+k,n*m+i,1,x*k);

 35                   insert(n*m+i,(j-1)*n+k,0,-x*k);

 36                 end;

 37             end;

 38         for i:=1 to n*m do

 39           begin

 40             insert(s,i,1,0);

 41             insert(i,s,0,0);

 42           end;

 43         for i:=1 to n do

 44           begin

 45             insert(n*m+i,t,1,0);

 46             insert(t,n*m+i,0,0);

 47           end;

 48 end;

 49  

 50 function dfs(x,flow:longint):longint;

 51 var

 52         i,d,min:longint;

 53 begin

 54         if x=t then

 55         begin

 56           inc(ans,flow*dis[t]);

 57           exit(flow);

 58         end;

 59         i:=first[x];

 60         flag[x]:=time;

 61         dfs:=0;

 62         while i<>0 do

 63           begin

 64             d:=dis[x]+w[i]-dis[last[i]];

 65             min:=flow;

 66             if min>liu[i] then min:=liu[i];

 67             if (liu[i]>0) and (d<f[last[i]]) then f[last[i]]:=d;

 68             if (d=0) and (flag[last[i]]<>time) and (min>0) then

 69             begin

 70               d:=dfs(last[i],min);

 71               dec(flow,d);

 72               inc(dfs,d);

 73               inc(liu[i xor 1],d);

 74               dec(liu[i],d);

 75             end;

 76             if flow=0 then break;

 77             i:=next[i];

 78           end;

 79 end;

 80  

 81 procedure work;

 82 var

 83         del,i:longint;

 84 begin

 85         while true do

 86           begin

 87             for i:=s to t do

 88               f[i]:=inf;

 89             inc(time);

 90             dfs(s,inf);

 91             del:=inf;

 92             for i:=s to t do

 93               if (flag[i]<>time) and (f[i]<del) then del:=f[i];

 94             if del=inf then break;

 95             for i:=s to t do

 96               if flag[i]<>time then inc(dis[i],del);

 97           end;

 98         writeln(ans/n:0:2);

 99 end;

100  

101 begin

102         init;

103         work;

104 end.
View Code

 

你可能感兴趣的:(2007)