问题 E: 修车
时间限制: 1 Sec 内存限制: 128 MB
题目描述
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
输入
第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。
输出
最小平均等待时间,答案精确到小数点后2位。
样例输入
2 2
3 2
1 4
样例输出
1.50
提示
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
Code
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int m,n,ans,a[62][10],flow[602][602],cost[602][602];
int dis[602],pre[602],Que[6002];
bool inq[602];
int main() {
scanf("%d%d",&m,&n);
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j)
scanf("%d",&a[i][j]);
flow[0][i]=1;
cost[0][i]=0;
}
for (int i=1; i<=m; ++i)
for (int j=1; j<=n; ++j) {
flow[n*i+j][(m+1)*n+1]=1;
cost[n*i+j][(m+1)*n+1]=0;
}
for (int i=1; i<=n; ++i)
for (int j=1; j<=m; ++j)
for (int k=1; k<=n; ++k) {
flow[i][n*j+k]=1;
cost[i][n*j+k]=k*a[i][j];
cost[n*j+k][i]=-k*a[i][j];
}
while (1) {
int p=(m+1)*n+1,l=3000,r=3001;
for (int i=0; i<=p; ++i) dis[i]=INF,inq[i]=0;
dis[0]=0;
inq[0]=1;
Que[r]=0;
while (l<r) {
int u=Que[++l];
inq[u]=0;
for (int i=0; i<=p; ++i)
if (flow[u][i]>0&&cost[u][i]+dis[u]<dis[i]) {
dis[i]=dis[u]+cost[u][i];
pre[i]=u;
if (!inq[i]) {
inq[i]=1;
if (l==r||dis[i]<dis[Que[l+1]])
Que[l--]=i;
else Que[++r]=i;
}
}
}
if (dis[p]==INF) break;
for (int i=p; i!=0; i=pre[i]) {
flow[pre[i]][i]-=1;
flow[i][pre[i]]+=1;
}
ans+=dis[p];
}
printf("%.2f\n",1.0*ans/n);
}
/**************************************************************
Problem: 4135
User: WC006
Language: C++
Result: 正确
Time:104 ms
Memory:4564 kb
****************************************************************/