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.