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

Sample Output

1.50

HINT

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

Source

网络流的精彩之处就在于建图,这道题的建图方法就特别好玩。

首先,题目要求的是最小的顾客平均等待的时间,由于总的汽车数一定是n,所以我们只需要求出最小的总的等待时间就可以了。

由于每个人同一时间只能修1辆,每辆车修一次就够了(流量限制),用m个人修n次即可(流量守恒),有网络流的性质,而且求极值,所以想到用最小费用最大流解决。

但还有一个问题,边的权值只有一个,那如何合并时间(次序)与修车费用这两个维度呢?

由于可以同时工作,我们分别考虑每个人。假定 i 辆车是某人 倒数第 j 个修的,那么这辆车对总的等待时间的贡献就是 修理i的费用×j(修理时,有 j-1 辆车在等待其修理完成)

所以我们这样建图:

每个人i拆成多个点,表示这个人 倒数第k次修理车(k最大为n),对某个单点,与表示车辆j的点添加一条流量为1,权值为 k×cost[i][j]

为保证每辆车只修理一次,从表示车辆的点向汇点连一条流量为1的边即可

代码:

 /*
* @FileName: /media/shan/Study/代码与算法/OJ(无法分类的题目)/BZOJ/1070/bzoj1070.cpp
* @Author: Pic
* @Created Time: 2017年11月21日 星期二 13时51分31秒
*/
#include <bits/stdc++.h>
using namespace std;
const int maxn=;
const int INF=0x3f3f3f3f;
struct Edge
{
int from,to,cap,flow,cost;
Edge(){}
Edge(int f,int t,int c,int fl,int co):from(f),to(t),cap(c),flow(fl),cost(co){}
};
struct MCMF
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool inq[maxn]; //是否在队列
int d[maxn]; //Bellman_ford单源最短路径
int p[maxn]; //p[i]表从s到i的最小费用路径上的最后一条弧编号
int a[maxn]; //a[i]表示从s到i的最小残量 //初始化
void init(int n,int s,int t)
{
this->n=n, this->s=s, this->t=t;
edges.clear();
for(int i=;i<n;++i) G[i].clear();
} //添加一条有向边
void AddEdge(int from,int to,int cap,int cost)
{
edges.push_back(Edge(from,to,cap,,cost));
edges.push_back(Edge(to,from,,,-cost));
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} //求一次增广路
bool BellmanFord(int &flow, int &cost)
{
for(int i=;i<n;++i) d[i]=INF;
memset(inq,,sizeof(inq));
d[s]=, a[s]=INF, inq[s]=true, p[s]=;
queue<int> Q;
Q.push(s);
while(!Q.empty())
{
int u=Q.front(); Q.pop();
inq[u]=false;
int len=G[u].size();
for(int i=;i<len;++i)
{
Edge &e=edges[G[u][i]];
if(e.cap>e.flow && d[e.to]>d[u]+e.cost)
{
d[e.to]= d[u]+e.cost;
p[e.to]=G[u][i];
a[e.to]= min(a[u],e.cap-e.flow);
if(!inq[e.to]){ Q.push(e.to); inq[e.to]=true; }
}
}
}
if(d[t]==INF) return false;
flow +=a[t];
cost +=a[t]*d[t];
int u=t;
while(u!=s)
{
edges[p[u]].flow += a[t];
edges[p[u]^].flow -=a[t];
u = edges[p[u]].from;
}
return true;
} //求出最小费用最大流
int Min_cost()
{
int flow=,cost=;
while(BellmanFord(flow,cost));
return cost;
}
}MM;
int c[maxn][maxn];
int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
int m,n;
while(~scanf("%d%d",&m,&n)){
int s=n*m+n+;
int t=s+;
MM.init(t+,s,t);
for(int i=;i<n;i++){
for(int j=;j<m;j++){
scanf("%d",&c[i][j]);
}
}
for(int i=;i<m;i++){
for(int j=;j<n;j++){
for(int k=;k<n;k++){
MM.AddEdge(i*n+j,n*m+k,,c[k][i]*(n-j));
}
}
}
for(int i=;i<n*m;i++){
MM.AddEdge(s,i,,);
}
for(int i=n*m;i<n*m+n;i++){
MM.AddEdge(i,t,,);
}
int res=MM.Min_cost();
printf("%.2lf\n",res*1.0/n);
} return ;
}

点我点我

BZOJ1070: [SCOI2007]修车(最小费用最大流,思维)的更多相关文章

  1. BZOJ1070[SCOI2007]修车——最小费用最大流

    题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待 ...

  2. BZOJ 1070: [SCOI2007]修车 [最小费用最大流]

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 4936  Solved: 2032[Submit][Status] ...

  3. BZOJ-1070 修车 最小费用最大流+拆点+略坑建图

    1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3624 Solved: 1452 [Submit][Status] ...

  4. [bzoj1070][SCOI2007]修车_费用流

    修车 bzoj-1070 SCOI-2007 题目大意:有m个人要修n台车,每个工人修不同的车的时间不同,问将所有的车都修完,最少需要花费的时间. 注释:$2\le m\le 9$,$1\le n \ ...

  5. bzoj1070: [SCOI2007]修车(费用流)

    1070: [SCOI2007]修车 题目:传送门 题解: 一道挺简单的费用流吧...胡乱建模走起 贴个代码... #include<cstdio> #include<cstring ...

  6. 2018.10.13 bzoj1070: [SCOI2007]修车(费用流)

    传送门 费用流经典题目. 自我感觉跟TheWindy′sThe Windy'sTheWindy′s很像. 利用费用提前计算的思想来建图就行了. 代码: #include<bits/stdc++. ...

  7. bzoj 1070 [SCOI2007]修车(最小费用最大流)

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3515  Solved: 1411[Submit][Status] ...

  8. [BZOJ1070][SCOI2007]修车 费用流

    1070: [SCOI2007]修车 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 6209  Solved: 2641[Submit][Status] ...

  9. 洛谷 P2053 [SCOI2007]修车(最小费用最大流)

    题解 最小费用最大流 n和m是反着的 首先, \[ ans = \sum{cost[i][j]}*k \] 其中,\(k\)为它在当前技术人员那里,排倒数第\(k\)个修 我们可以对于每个技术人员进行 ...

随机推荐

  1. 关于泛型擦除的知识(来源于csdn地址:https://blog.csdn.net/briblue/article/details/76736356)

    泛型,一个孤独的守门者. 大家可能会有疑问,我为什么叫做泛型是一个守门者.这其实是我个人的看法而已,我的意思是说泛型没有其看起来那么深不可测,它并不神秘与神奇.泛型是 Java 中一个很小巧的概念,但 ...

  2. 3-MySQL DBA笔记-开发基础

    第二部分 开发篇 本篇首先讲述数据库开发的一些基础知识,如关系数据模型.常用的SQL语法.范式.索引.事务等,然后介绍编程开发将会涉及的数据库的一些技巧,最后结合生产实际,提供一份开发规范供大家参考. ...

  3. C#动态生成Word文档并填充数据

    C#也能动态生成Word文档并填充数据 http://www.cnblogs.com/qyfan82/archive/2007/09/14/893293.html 引用http://blog.csdn ...

  4. [转载]IMDB文件格式

    [转载]IMDB文件格式 来源:LMDB的全称是Lightning Memory-Mapped Database,闪电般的内存映射数据库.它文件结构简单,一个文件夹,里面一个数据文件,一个锁文件.数据 ...

  5. HTML类

    class Html: def __init__(self,name): self.name = name @staticmethod def full_name(): print('全称:Hype ...

  6. TypeScript入门二:基本数据类型

    浅析基本数据类型 TypeScript类型解析 一.浅析基本数据类型 首先有一个问题TypeScript是一门编译型语言?还是解释性语言?显然已经不能被这两个分类来区分,TypeScript的并不是为 ...

  7. 统一用户认证系统CUAS实现要点

    背景: 基于目前存在多套员工使用的日常工作子系统,现状为各系统各自有一套用户体系,员工需要记住各系统的用户名.密码等信息,还需要登录多个系统,重复工作量颇多.统一用户认证组件将用户名.密码等信息统一存 ...

  8. java web开发跨域问题

    分布式环境,前后端分离背景下跨域问题 1.1 设置页面document.domain去把2个页面之间的跨域交互统一 一级域名相同的情况下 调用者和页面提供者进行一个协调 页面提供者要在document ...

  9. mac上配置apidoc环境

    1. 安装node.js 和npm 前往 https://nodejs.org/en/ 下载node.js的最新版本,双击.pkg进行安装 在终端输入 node -v ,如正确输出版本号即安装成功 ( ...

  10. GOLANG多态的特征是通过接口来实现的 GOLANG多态形式之一:多态参数

    GOLANG多态的简单实现 //多态的特征是通过接口来实现的 //多态形式之一:多态参数 package main import( "fmt" _"sort" ...