1070: [SCOI2007]修车
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
3 2
1 4
Sample Output
1.50
HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
把每个维修人员拆成n个,每辆车与这n个点连边,表示这辆车是倒数第k个修的,那么剩下k辆车就要多等a[i][j]*k的时间
所以做一个费用流就好了。。。
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 1005 14 #define maxm 65 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read(){ 24 int x=0,f=1;char ch=getchar(); 25 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 26 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 27 return x*f; 28 } 29 int n,m,tot=1; 30 double ans; 31 int head[maxn],q[maxn],d[maxn],from[maxn],a[maxm][maxm]; 32 bool inq[maxn]; 33 struct edge{ 34 int go,next,from,w,c; 35 }e[100005]; 36 void insert(int u,int v,int w,int c){ 37 e[++tot]=(edge){v,head[u],u,w,c};head[u]=tot; 38 } 39 void ins(int u,int v,int w,int c){ 40 insert(u,v,w,c);insert(v,u,0,-c); 41 } 42 bool spfa(){ 43 int h=0,t=1; 44 for0(i,maxn)d[i]=inf; 45 q[h]=0;d[0]=0;inq[0]=1; 46 while(h!=t){ 47 int x=q[h++];if(h==maxn)h=0; 48 for4(i,x) 49 if(e[i].w&&d[x]+e[i].c<d[y]){ 50 d[y]=d[x]+e[i].c; 51 from[y]=i; 52 if(!inq[y]){ 53 inq[y]=1; 54 q[t++]=y; 55 if(t==maxn)t=0; 56 } 57 } 58 inq[x]=0; 59 } 60 if(d[maxn]==inf)return 0; 61 else return 1; 62 } 63 void mcf(){ 64 int x=inf; 65 for(int i=from[maxn];i;i=from[e[i].from]) 66 x=min(x,e[i].w); 67 for(int i=from[maxn];i;i=from[e[i].from]){ 68 e[i].w-=x;e[i^1].w+=x;ans+=e[i].c*x; 69 } 70 } 71 int main(){ 72 //freopen("input.txt","r",stdin); 73 //freopen("output.txt","w",stdout); 74 m=read();n=read(); 75 for1(i,n) 76 for1(j,m) 77 a[i][j]=read(); 78 for1(i,n*m)ins(0,i,1,0); 79 for(int i=n*m+1;i<=n*m+n;i++) 80 ins(i,maxn,1,0); 81 for1(i,m) 82 for1(j,n) 83 for1(k,n) 84 ins((i-1)*n+j,n*m+k,1,a[k][i]*j); 85 while(spfa())mcf(); 86 printf("%.2lf",ans/n); 87 return 0; 88 }