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)
将M个工作人员拆成N个点
拆后的M员工的第k个裂点连某辆车,表示该车是倒数第k个被修的车
因为是倒数第k,所以费用自然要加上后面排队的车的费用
算是一种逆向思维吧
MD n和m搞反了……找错找了半天qwq
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<queue> #define MAXN (50000+10) #define MAXM (5000000+10) using namespace std; queue<int>q; bool visit[MAXN]; int pre[MAXN]; int n,m,k,s,e=4999,Ans,Fee; int num_edge; int head[MAXN]; int dis[MAXN]; bool used[MAXN]; int INF; int t[1000][1000]; struct node { int to; int next; int Flow;//残留网络 int Cost; } edge[MAXM*2]; void add(int u,int v,int l,int c) { edge[++num_edge].to=v; edge[num_edge].next=head[u]; edge[num_edge].Flow=l; edge[num_edge].Cost=c; head[u]=num_edge; } bool Spfa(int s,int e) { memset(pre,-1,sizeof(pre)); memset(dis,0x7f,sizeof(dis)); q.push(s); dis[s]=0; used[s]=true; while (!q.empty()) { int x=q.front(); q.pop(); for (int i=head[x]; i!=0; i=edge[i].next) if (dis[x]+edge[i].Cost<dis[edge[i].to] && edge[i].Flow>0) { dis[edge[i].to]=edge[i].Cost+dis[x]; pre[edge[i].to]=i; if (!used[edge[i].to]) { used[edge[i].to]=true; q.push(edge[i].to); } } used[x]=false; } return (dis[e]!=INF); } int MCMF(int s,int e) { Ans=0,Fee=0; while (Spfa(s,e)) { int d=INF; for (int i=e; i!=s; i=edge[((pre[i]-1)^1)+1].to) d=min(d,edge[pre[i]].Flow); for (int i=e; i!=s; i=edge[((pre[i]-1)^1)+1].to) { edge[pre[i]].Flow-=d; edge[((pre[i]-1)^1)+1].Flow+=d; } Ans+=d; Fee+=d*dis[e]; } return Fee; } int main() { memset(&INF,0x7f,sizeof(INF)); scanf("%d%d",&m,&n); for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) scanf("%d",&t[i][j]); for (int i=1;i<=m*n;++i) { add(s,i,1,0); add(i,s,0,0); } for (int i=1;i<=n;++i) { add(m*n+i,e,1,0); add(e,m*n+i,0,0); } for (int i=1;i<=n;++i) for (int j=1;j<=m;++j) for (int k=1;k<=n;++k) { add((j-1)*n+i,m*n+k,1,i*t[k][j]); add(m*n+k,(j-1)*n+i,0,-i*t[k][j]); } double ans=MCMF(s,e); printf("%.2lf\n",ans/n); }