题目描述

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

说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。

输入输出格式

输入格式:

第一行有两个数M,N,表示技术人员数与顾客数。

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

输出格式:

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

输入输出样例

输入样例#1: 复制

2 2
3 2
1 4
输出样例#1: 复制

1.50

说明

(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】修车(费用流)的更多相关文章

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

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

  2. [bzoj1070][SCOI2007]修车——费用流

    题目大意: 传送门 题解: 本题和(POJ3686)[http://poj.org/problem?id=3686]一题一模一样,而且还是数据缩小以后的弱化版QAQ,<挑战程序设计竞赛>一 ...

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

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

  4. 【BZOJ1070】[SCOI2007]修车 费用流

    [BZOJ1070][SCOI2007]修车 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的. ...

  5. bzoj 1070: [SCOI2007]修车 费用流

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

  6. P2053 [SCOI2007]修车 费用流

    $ \color{#0066ff}{ 题目描述 }$ 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M ...

  7. 【BZOJ 1070】[SCOI2007]修车 费用流

    就是拆个点限制一下(两点一排一大片),这道题让我注意到了限制这个重要的词.我们跑网络流跑出来的图都是有一定意义的,一般这个意义就对应了问题的一种方案,一般情况下跑一个不知道对不对的方案是相对容易的我们 ...

  8. [SCOI2007]修车 费用流

    ---题面--- 题解: 因为我们并不需要知道准确方案,而人数固定,要使得平均等待时间最小,也就是要使得总的等待时间最小. 因此我们将工人按每个时刻拆点,拆完之后向车子连边,流量为1,费用为k * 维 ...

  9. [SCOI2007]修车 费用流 BZOJ 1070

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

  10. BZOJ.1070.[SCOI2007]修车(费用流SPFA)

    题目链接 /* 神tm看错题*2.. 假如人员i依次维修W1,W2,...,Wn,那么花费的时间是 W1 + W1+W2 + W1+W2+W3... = W1*n + W2*(n-1) + ... + ...

随机推荐

  1. leetcode481

    public class Solution { public int MagicalString(int n) { ) ; ) ; ]; a[] = ; a[] = ; a[] = ; , tail ...

  2. springMVC第一天

    这些是springMVC3.2所用到的jar包 web.xml配置 <?xml version="1.0" encoding="UTF-8"?> & ...

  3. spring中aop原理

  4. jquery与原生js比较

    以选择符为例,类似于这种 $(".class") 方式,在ie里面,肯定比$("#id") 低很多,而对于chrome和firefox,则因为提供了getEle ...

  5. libevent源码深度剖析九

    libevent源码深度剖析九 ——集成定时器事件 张亮 现在再来详细分析libevent中I/O事件和Timer事件的集成,与Signal相比,Timer事件的集成会直观和简单很多.Libevent ...

  6. Yii 2 load() 和 save()

    我这里用的数据库是mongo 数据库 为栗子: public function load($data, $formName = null) { $scope = $formName === null ...

  7. linux 软链接 硬链接

    查看文件sun.txt   加上参数i 是显示节点 inode [root@bogon test]# ls -li sun.txt 10006225 -rw-r--r--. 1 root root 0 ...

  8. 关于getchar的一些思考

    这个问题是有一段代码引起的: 代码1: #include<iostream> using namespace std; int main() { char t; t=getchar(); ...

  9. 7-python自定义opener

    Handler处理器 和 自定义Opener opener是 urllib2.OpenerDirector 的实例,我们之前一直都在使用的urlopen,它是一个特殊的opener(也就是模块帮我们构 ...

  10. Ubuntu16.04 ARM平台移植libcurl curl-7.63.0

    libcurl是免费的轻量级的客户端网络库,支持DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS,POP3, P ...