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 }
时间: 2024-10-11 12:36:00

BZOJ1070 修车-费用网络流的相关文章

bzoj1070 修车&amp;&amp; bzoj2879美食节 【费用流】

bzoj1070: 把每个工人拆成汽车那么多个点,假如说 工人(i, j) 和 汽车k 连边,那就代表第i个工人倒数第j个修汽车k,那么这条边对以后的贡献就是k*time[i修k]. 1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a,

[BZOJ1070] [SCOI2007] 修车 (费用流 &amp; 动态加边)

Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. Output 最小平均等待时间,答案精确到小数点后2位

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

1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MB Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. Input 第一行有两个m,n,表示技术人员数与顾客数. 接下来n行,每行m个整数.第

BZOJ SCOI 2007 修车 费用流

题目大意:有一些车和一些修车的人,给出每个人修每个车的时间,问所有人等待的最短平均时间是多少. 思路:记得POJ有一个和这个很像的题,做法是一样的.对于每个人修车的时候,我们只考虑他修车的时间对在它之后修车的人的时间的影响,因此我们只要考虑每一辆车是倒数第几个修的就可以了,然后朴素的建图,跑朴素的费用流,就可以过. CODE: #include <queue> #include <cstdio> #include <cstring> #include <ioman

BZOJ 1070 修车(费用流)

如果能想到费用流,这道题就是显然了. 要求所有人的等待平均时间最小,也就是所有人的总等待时间最小. 每辆车只需要修一次,所以s连每辆车容量为1,费用为0的边. 现在需要把每个人拆成n个点,把车和每个人的第k个点连一条容量为1,费用为cost[i][j]*k的边. 最后把每个人拆完后的点向汇点连一条容量为1,费用为0的边. #include<iostream> #include<cstdio> #include<cstring> #define inf 0x7ffffff

UVA 10594-Date Flow(无向图的最小费用网络流+题目给的数据有误)

题意:给一个有N个点的无向图,要求从1向N传送一定的数据,每条边的容量是一定的,如果能做到,输出最小的费用,否则输出Impossible. 解析:由于是无向图,所以每个有连接的两个点要建4条边,分别是edge(from,to,cap,0,cost),edge(to,from,0,0,-cost),edge(to,from,cap,0,cost),edge(from,to,0,0,-cost) 设置一个起点0,0与1连一条有向边,容量为题目给出的D,这样限制了最大的流量,如果最后的流量不等于D,则

【bzoj1070 修车】(pdt)

题目描述: 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 数据范围: 1<=N<=800, 0<=M<=15000 题解: 现在先假装只有一个技术人员修n辆车,那么等待总时间为a1+(a1+a2)+(a1+a2+a3)+...(a1+a2+a3+..+an)=

P2053 [SCOI2007]修车 费用流

https://www.luogu.org/problemnew/show/P2053 题意 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 思路 左边放n个点,表示n辆车.右边放m * n个点,表示m个工人,拆除n个点表示不同阶段.即如果第i辆车连上了第m个工人的第k个阶段

luogu P2053 [SCOI2007]修车 |费用流

题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小. 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间. 输入格式 第一行有两个数M,N,表示技术人员数与顾客数. 接下来n行,每行m个整数.第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T. 输出格式 最小平均等待时间,答案精确到小数点后2位. #includ