BZOJ1070 修车-费用网络流

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ1070 修车-费用网络流相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=1070

Description

  同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同
的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最
小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

Input

  第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人
员维修第i辆车需要用的时间T。

Output

  最小平均等待时间,答案精确到小数点后2位。

HINT

数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)

 

//.............

 1 #include<iostream>
 2 #include<vector>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 using namespace std;
 7 const int maxn=3000;
 8 const int inf=1<<30;
 9 struct Edge{
10     int from,to,cap,flow,cost;
11 };
12 struct MCMF{
13     int n,m,s,t;
14     vector<Edge> edges;
15     vector<int> G[maxn];
16     int inq[maxn];
17     int d[maxn];
18     int p[maxn];
19     int a[maxn];
20     void init(int n){
21         this->n=n;
22         for(int i=1;i<=n;i++) G[i].clear();
23         edges.clear();
24     }
25     void addEdge(int from,int to,int cap,int cost){
26         edges.push_back((Edge){from,to,cap,0,cost});
27         edges.push_back((Edge){to,from,0,0,-cost});
28         m=edges.size();
29         G[from].push_back(m-2);
30         G[to].push_back(m-1);
31     }
32     bool BF(int s,int t,int& flow,int& cost){
33         for(int i=1;i<=n;i++) d[i]=inf;
34         memset(inq,0,sizeof(inq));
35         d[s]=0;inq[s]=1;p[s]=0;a[s]=inf;
36         
37         queue<int> Q;
38         Q.push(s);
39         while(!Q.empty()){
40             int u=Q.front();Q.pop();
41             inq[u]=0;
42             for(int i=0;i<G[u].size();i++){
43                 Edge& e=edges[G[u][i]];
44                 if(e.cap>e.flow&&d[e.to]>d[u]+e.cost){
45                     d[e.to]=d[u]+e.cost;
46                     p[e.to]=G[u][i];
47                     a[e.to]=min(a[u],e.cap-e.flow);
48                     if(!inq[e.to]){
49                         Q.push(e.to);
50                         inq[e.to]=1;
51                     }
52                 }
53             }
54         }
55         if(d[t]==inf) return false;
56         flow+=a[t];
57         cost+=d[t]*a[t];
58         int u=t;
59         while(u!=s){
60             edges[p[u]].flow+=a[t];
61             edges[p[u]^1].flow-=a[t];
62             u=edges[p[u]].from;
63         }
64         return true;
65     }
66     int MinCost(int s,int t){
67         int flow=0,cost=0;
68         while(BF(s,t,flow,cost));
69         return cost;
70     }
71 };
72 MCMF solver;
73 int t[61][10];
74 int main()
75 {
76     int n,m;
77     scanf("%d %d",&m,&n);
78     solver.init(2+n*(m+1));
79     for(int i=1;i<=n;++i)
80         for(int j=1;j<=m;++j)
81             scanf("%d",&t[i][j]);
82     for(int i=1;i<=n;++i)
83         solver.addEdge(1,1+i,1,0);
84     for(int i=1;i<=n*m;++i)
85         solver.addEdge(1+n+i,2+n+n*m,1,0);
86     for(int i=1;i<=n;i++){
87         for(int j=1;j<=m;j++){
88             int T=t[i][j];
89             for(int k=1;k<=n;k++)
90                 solver.addEdge(1+i,1+n+(j-1)*n+k,1,T*k);
91         }
92     }
93     printf("%.2lf",((double)solver.MinCost(1,2+n*(m+1)))/n);
94     return 0;
95 }

 

以上是关于BZOJ1070 修车-费用网络流的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1070: [SCOI2007]修车 费用流

[BZOJ1070][SCOI2007]修车 费用流

BZOJ 1070 修车(费用流)

bzoj 1070: [SCOI2007]修车 -- 费用流

bzoj 1070 [SCOI2007]修车 费用流

bzoj 1070: [SCOI2007]修车最小费用最大流