BZOJ 1070 拆点 费用流
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 5860 Solved: 2487
[Submit][Status][Discuss]
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
把修车师傅拆成 n*m个修车师傅 然后具体 // 还是看这里吧http://hzwer.com/2877.html
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=1000; 7 const int M=5e5+88; 8 const int INF=0x3f3f3f3f; 9 int mp[88][11]; 10 struct node{ 11 int u,v,flow,cost,next; 12 }e[M]; 13 int tot,head[N],pre[N],C[N],F[N],V[N],n,m; 14 void add(int u,int v,int flow,int cost){ 15 e[tot].u=u;e[tot].v=v;e[tot].flow=flow;e[tot].cost=cost;e[tot].next=head[u];head[u]=tot++; 16 e[tot].u=v;e[tot].v=u;e[tot].flow=0;e[tot].cost=-cost;e[tot].next=head[v];head[v]=tot++; 17 } 18 int SPFA(int s,int t){ 19 memset(pre,-1,sizeof(pre)); 20 for(int i=1;i<=t+1;++i) F[i]=0,C[i]=INF,V[i]=0; 21 queue<int>Q; 22 Q.push(s); 23 C[0]=0,F[0]=INF,V[0]=1; 24 while(!Q.empty()){ 25 int u=Q.front(); 26 Q.pop(); 27 V[u]=0; 28 for(int i=head[u];i+1;i=e[i].next){ 29 int v=e[i].v,f=e[i].flow,c=e[i].cost; 30 if(f>0&&C[v]>C[u]+c) { 31 C[v]=C[u]+c; 32 pre[v]=i; 33 F[v]=min(f,F[u]); 34 if(!V[v]) V[v]=1,Q.push(v); 35 } 36 } 37 } 38 return F[t]; 39 } 40 int MCMF(int s,int t){ 41 int ans=0,temp; 42 while(temp=SPFA(s,t)){ 43 for(int i=pre[t];i+1;i=pre[e[i].u]) { 44 ans+=temp*e[i].cost; 45 e[i].flow-=temp; 46 e[i^1].flow+=temp; 47 } 48 } 49 return ans; 50 } 51 int main(){ 52 memset(head,-1,sizeof(head)); 53 scanf("%d%d",&m,&n); 54 for(int i=1;i<=n;++i) 55 for(int j=1;j<=m;++j) 56 scanf("%d",&mp[i][j]);//mp[i][j],顾客--修车人员 57 int st=0,ed=m*n+n+1; 58 for(int i=1;i<=n*m;++i) add(0,i,1,0); 59 for(int i=n*m+1;i<=n*m+n;++i) add(i,ed,1,0); 60 for(int i=1;i<=m;++i) 61 for(int j=1;j<=n;++j) 62 for(int k=1;k<=n;++k) 63 add((i-1)*n+j,n*m+k,1,mp[k][i]*j); 64 int ct=MCMF(st,ed); 65 printf("%.2f\n",double(ct)/n); 66 }