同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。
最小平均等待时间,答案精确到小数点后2位。
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
这题用网络流简直了。。。
将每个工人拆成n个点,分别代表第i个工人正在修倒数第j辆车将n辆车分别与这些点建边,费用为t[i][j]*k同时超级源超级汇等。。各边容量均为1,最后一遍最小费用最大流
为什么这样做呢?因为维修一辆车的时间只对其后面的维修造成影响,如果它是该工人修的倒数第k辆车,那么影响k次
#include<iostream> #include<cstdio> #include<queue> #include<vector> using namespace std; const int maxn = 70; typedef double DB; vector <int> v[maxn*maxn*maxn]; queue <int> q; struct E{ int from,to,cap,flow,w; }G[1000000]; DB cost = 0; int n,m,cnt = 0,t[maxn][maxn],dis[maxn*maxn*maxn],fa[maxn*maxn*maxn],a[maxn*maxn*maxn]; bool vis[maxn*maxn*maxn]; void Add(int from,int to,int c,int w) { v[from].push_back(cnt); G[cnt++] = (E){from,to,c,0,w}; v[to].push_back(cnt); G[cnt++] = (E){to,from,0,0,-w}; } bool spfa() { for (int i = 1; i <= m+n*m+1; i++) dis[i] = ~0U>>1,vis[i] = 0; dis[0] = 0; vis[0] = 1; a[0] = ~0U>>1; q.push(0); while (!q.empty()) { int k = q.front(); q.pop(); vis[k] = 0; for (int i = 0; i < v[k].size(); i++) { E e = G[v[k][i]]; if (e.cap > e.flow && dis[e.to] > dis[k] + e.w) { dis[e.to] = dis[k] + e.w; a[e.to] = min(a[k],e.cap - e.flow); fa[e.to] = v[k][i]; if (!vis[e.to]) { vis[e.to] = 1; q.push(e.to); } } } } if (dis[m+m*n+1] == ~0U>>1) return 0; int A = a[m+m*n+1]; cost += (DB)(A)*(DB)(dis[m+m*n+1]); int u = m+m*n+1; while (u) { G[fa[u]].flow += A; G[fa[u]^1].flow -= A; u = G[fa[u]].from; } return 1; } int main() { #ifdef YZY freopen("yzy.txt","r",stdin); #endif cin >> n >> m; for (int i = 1; i <= m; i++) for (int j = 1; j <= n; j++) scanf("%d",&t[j][i]); for (int i = 1; i <= m; i++) Add(0,i,1,0); for (int i = 1; i <= m; i++) for (int j = m+1; j <= m+n*m; j++) { int w = (j-m-1)/m + 1; int k = (j-m)%m; if (!k) k = m; Add(i,j,1,t[w][i]*k); } for (int i = m+1; i <= m+n*m; i++) Add(i,m+n*m+1,1,0); while (spfa()); printf("%.2f",cost/(DB)(m)); return 0; }