bzoj1070【SCOI2007】修车(费用流)
题目描述
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。
说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
输入输出格式
输入格式:
第一行有两个数M,N,表示技术人员数与顾客数。
接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。
输出格式:
最小平均等待时间,答案精确到小数点后2位。
输入输出样例
说明
(2<=M<=9,1<=N<=60), (1<=T<=1000)
题解
这篇还是写得详细一点好了……因为不是很懂……
我们考虑一下,如果一个工人修车的序列为$W_1,W_2,W_3...W_n$
那么对于这几辆车的车主而言,他们等待的总时间是$\sum _{i=1}^n W_i*(n-i+1)=nW_1+(n-1)W_2+...+W_n$(因为一个人在越前面修,会使后面更多的人要等待他的车修好)
然后因为平均时间最少,人数是不变的,所以得保证总时间最少
我们发现,如果把第$i$个人的车让第$j$个人在倒数第$k$个修(以下表示为$(i,j,k)$),那么对总时间的贡献是$T(i,j)*k$,其中$T(i,j)$表示第$j$个人修第$i$辆车的时间
然后因为每一辆车只能被一个人修,每一个人同一时间只能修一辆车
那么我们可以把$(j,k)$表示成一个状态,表示被第$j$个人在倒数第$k$个修,那么不难发现每一个状态只能被匹配一次,即不可能有两辆车同时被一个人在同一个顺序修
那么我们可以建一个二分图,左边是$n$辆车,右边是$n*m$个状态$(j,k)$(因为$k$不可能超过$n$),然后左边的每一个点向右边所有点连边,容量为$1$,费用为对应的$(i,j,k)$
然后因为每一辆车只会被修一次,所以从源点向所有车连容$1$费$0$的边
因为每一个人在同一时间只能修一辆车,所以右边所有状态向汇点连容$1$费$0$的边
当网络跑满的时候说明所有车都有人修了,然后又要时间最少,只要在此基础上求一个最小费用流即可
//minamoto
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#define inf 0x3f3f3f3f
#define id(i,j) (i-1)*n+j
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=,M=;
int ver[M],Next[M],head[N],edge[M],flow[M],tot=;
int vis[N],dis[N],disf[N],Pre[N],last[N],n,m,s,t;
queue<int> q;
inline void add(int u,int v,int f,int e){
ver[++tot]=v,Next[tot]=head[u],head[u]=tot,flow[tot]=f,edge[tot]=e;
ver[++tot]=u,Next[tot]=head[v],head[v]=tot,flow[tot]=,edge[tot]=-e;
}
bool spfa(){
memset(dis,0x3f,sizeof(dis));
while(!q.empty()) q.pop();
q.push(s),dis[s]=,disf[s]=inf,Pre[t]=-;
while(!q.empty()){
int u=q.front();q.pop(),vis[u]=;
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(flow[i]&&dis[v]>dis[u]+edge[i]){
dis[v]=dis[u]+edge[i],Pre[v]=u,last[v]=i;
disf[v]=min(disf[u],flow[i]);
if(!vis[v]) vis[v]=,q.push(v);
}
}
}
return ~Pre[t];
}
int dinic(){
int mincost=;
while(spfa()){
int u=t;mincost+=disf[t]*dis[t];
while(u!=s){
flow[last[u]]-=disf[t],flow[last[u]^]+=disf[t];
u=Pre[u];
}
}
return mincost;
}
int main(){
m=read(),n=read();
s=,t=n*m+n+;
for(int i=;i<=n;++i) add(s,i,,);
for(int i=;i<=m;++i)
for(int j=;j<=n;++j)
add(n+id(i,j),t,,);
for(int i=;i<=n;++i)
for(int j=;j<=m;++j){
int cost=read();
for(int k=;k<=n;++k){
add(i,n+id(j,k),,cost*k);
}
}
printf("%.2lf",(double)dinic()/n);
return ;
}
bzoj1070【SCOI2007】修车(费用流)的更多相关文章
- [BZOJ1070][SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 6209 Solved: 2641[Submit][Status] ...
- [bzoj1070][SCOI2007]修车——费用流
题目大意: 传送门 题解: 本题和(POJ3686)[http://poj.org/problem?id=3686]一题一模一样,而且还是数据缩小以后的弱化版QAQ,<挑战程序设计竞赛>一 ...
- [BZOJ1070] [SCOI2007] 修车 (费用流 & 动态加边)
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使 ...
- 【BZOJ1070】[SCOI2007]修车 费用流
[BZOJ1070][SCOI2007]修车 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的. ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- P2053 [SCOI2007]修车 费用流
$ \color{#0066ff}{ 题目描述 }$ 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M ...
- 【BZOJ 1070】[SCOI2007]修车 费用流
就是拆个点限制一下(两点一排一大片),这道题让我注意到了限制这个重要的词.我们跑网络流跑出来的图都是有一定意义的,一般这个意义就对应了问题的一种方案,一般情况下跑一个不知道对不对的方案是相对容易的我们 ...
- [SCOI2007]修车 费用流
---题面--- 题解: 因为我们并不需要知道准确方案,而人数固定,要使得平均等待时间最小,也就是要使得总的等待时间最小. 因此我们将工人按每个时刻拆点,拆完之后向车子连边,流量为1,费用为k * 维 ...
- [SCOI2007]修车 费用流 BZOJ 1070
题目描述 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待 ...
- BZOJ.1070.[SCOI2007]修车(费用流SPFA)
题目链接 /* 神tm看错题*2.. 假如人员i依次维修W1,W2,...,Wn,那么花费的时间是 W1 + W1+W2 + W1+W2+W3... = W1*n + W2*(n-1) + ... + ...
随机推荐
- Python Twisted网络编程框架与异步编程入门教程
原作出处:twisted-intro-cn 作者:Dave 译者:杨晓伟 luocheng likebeta 转载声明:版权归原作出处所有,转载只为让更多人看到这部优秀作品合集,如果侵权,请留言告知 ...
- Mycat实战之数据迁移(oracle -- mysql)
1.案例场景: Mycat 后面接一个 Oracle 实例与一个 MySQL 实例,假设用户表,订单表,转账记录表, Oracle 字符集为 GBK 的,MySQL 字符集则要求 UTF8的 完成用户 ...
- oracle语言基础
一.语言分类 1.DML(Data Manipulation Language,数据操作语言):用于对数据的操作. DML包括:(1)SELECT:查询数据 select * from temp; ...
- Python代码的编译
Python代码的编译 Python代码在解释执行之前,是会被编译成.pyc或者.pyo文件的,它们是中间字节码表示的文件,之后Python虚拟机才会去解释执行它们. 1.pyc文件 ======== ...
- Spring总结一:Srping快速入门
Sping是什么: Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用.Spring是于2003 年兴起的一个轻量级的J ...
- 08-Location总结图解
URI解析 首先要判断有没有精准匹配,能不能精准匹配.计算机里面没有什么这种差不多这种东西.跟人聊天才说差不多,最近过得怎么样啊,还行吧,差不多吧,这个不多是多还是不多啊. 预定义库->Gen ...
- elasticsearch2.x插件之一:marvel(配置)
Marvel是Elastic公司推出的商业监控方案,是用来监控Elasticsearch集群,历史状态的有力工具,便于性能优化以及故障诊断.监控主要分为六个层面,分别是集群层.节点层.索引层.分片层. ...
- laravel数据迁移(创建错误列不能创建)
创建数据表的命令 php artisan make:migration create_users_table 执行这个迁移的命令, php artisan migrate 其实感觉就像简单的方法创建数 ...
- python-memcached模块
memcache memcache介绍 memcache概念 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库 ...
- 19、SOAP安装,运用与比对结果解释
转载:http://www.dengfeilong.com/post/Soap2.html https://blog.csdn.net/zhu_si_tao/article/details/71108 ...