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)
听说这题也是经典题……为什么我见到的都是经典题
考虑第i个人修理第k辆车,后面还有j-1个人等着的情况。代价就是j*cost[k,i]
把所有维修人员拆点,拆成n*m个。点(i,j)表示第i个人在修倒数第j辆车,那么某辆车k向点(i,j)连的边,费用就是j*coss[k,i]
然后S向所有车连边,所有车分别向n*m个点连边,n*m个点向T连边
#include<cstdio> #include<iostream> #define LL long long #define inf 0x3fffffff #define S 0 #define T 1001 #define N 1010 #define p(x,y) (x-1)*m+y using namespace std; inline LL read() { LL x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct edge{int to,next,v,c,from;}e[100*N]; int head[N],dist[N],q[N],from[N]; int a[N][N]; bool mrk[N]; int n,m,cnt=1,ans; inline void ins(int u,int v,int w,int c) { e[++cnt].to=v; e[cnt].v=w; e[cnt].c=c; e[cnt].from=u; e[cnt].next=head[u]; head[u]=cnt; } inline void insert(int u,int v,int w,int c) { ins(u,v,w,c); ins(v,u,0,-c); } inline bool spfa() { for (int i=0;i<=T;i++)dist[i]=inf; int t=0,w=1; dist[S]=0;q[0]=S;mrk[S]=1; while (t!=w) { int now=q[t++];if (t==N-1)t=0; for (int i=head[now];i;i=e[i].next) if (e[i].v&&dist[now]+e[i].c<dist[e[i].to]) { dist[e[i].to]=dist[now]+e[i].c; from[e[i].to]=i; if (!mrk[e[i].to]) { mrk[e[i].to]=1; q[w++]=e[i].to; if (w==N-1)w=0; } } mrk[now]=0; } return dist[T]!=inf; } inline void mcf() { int x=inf; for (int i=from[T];i;i=from[e[i].from]) x=min(x,e[i].v); for (int i=from[T];i;i=from[e[i].from]) { e[i].v-=x; e[i^1].v+=x; ans+=x*e[i].c; } } int main() { m=read();n=read(); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) a[i][j]=read(); for (int i=1;i<=n;i++)insert(S,i,1,0); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { for (int k=1;k<=n;k++) insert(i,n+p(k,j),1,(n-k+1)*a[i][j]); insert(n+p(i,j),T,1,0); } while (spfa())mcf(); printf("%.2lf ",(double)ans/n); }