【BZOJ】【1070】【SCOI2007】修车
网络流/费用流
好神奇的建模= =
关键就是把每个技术员拆成n个点,表示这个技术员倒数第几个修的车子。。
考虑第i个工人,他修第j辆车只对后面要修的车有影响,而前面修过的车已经对当前没有影响了。
而这个影响就是后面每个将要修理的车都多等待了time的时间。
说一下我的思考过程吧:(好混乱……)
对于每辆车只修一次,所以每辆车跟S连(1,0)边(表示流量为1,费用为0)。
然后每辆车的修车时间怎么算呢?每辆车都跟每个修理工连边,这是肯定的……但是还有等待啊,等待的时间怎么算呢?
倒过来考虑,假如我们现在有一个修理方案,修理工A的修理顺序是1、2、4、6、7,那么他修1号车对于总等待时间的贡献就是time[1][A]*5,因为后面四辆车还得等着嘛;以此类推,修4号车的cost为time[4][A]*3……即倒数第 j 辆车的修理时间cost为time[car[j]][A]*j
已知了修理方案我们怎么用费用流的模型来表示出来它呢?
我们可以把每个修理工拆开!将一个修理工拆成n个点,第 j 个点表示这个修理工按序修的倒数第 j 辆车,由这个点连向所有车,流量为1,cost就为time[ 这辆车 ][ 这个修理工 ]*j,那么刚刚的例子中,第1号车就连向了修理工A的倒数第5个点,2号车连着倒数第4个点……
如果最优方案中A修的车没有5辆?而是1、4、7?那第一辆车肯定就不会去连倒数第5个点了,因为是最小费用流嘛,它就会连到倒数第3个点,4号车就会连到倒数第二个点……
这样建图,其实是把所有的方案都枚举了出来,每种修理方案都对应着一个流!
UPD:2015-03-19 09:22:15
VFK:裸的二分图最小权匹配,用KM来写会更快……
/**************************************************************
Problem: 1070
User: Tunix
Language: C++
Result: Accepted
Time:464 ms
Memory:6012 kb
****************************************************************/ //BZOJ 1070
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
#define CC(a,b) memset(a,b,sizeof(a))
using namespace std;
int getint(){
int v=,sign=; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') sign=-; ch=getchar();}
while(isdigit(ch)) {v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=,M=,INF=~0u>>;
const double eps=1e-;
/*******************template********************/
int n,m,ans,tim[][];
struct edge{int from,to,v,c;};
struct Net{
edge E[M];
int head[N],next[M],cnt;
void ins(int x,int y,int z,int c){
E[++cnt]=(edge){x,y,z,c};
next[cnt]=head[x]; head[x]=cnt;
}
void add(int x,int y,int z,int c){
ins(x,y,z,c); ins(y,x,,-c);
}
int from[N],Q[M],S,T,d[N];
bool inq[N];
bool spfa(){
int l=,r=-;
F(i,S,T) d[i]=INF;
d[S]=; Q[++r]=S; inq[S]=;
while(l<=r){
int x=Q[l++];
inq[x]=;
for(int i=head[x];i;i=next[i])
if (E[i].v && d[x]+E[i].c<d[E[i].to]){
d[E[i].to]=d[x]+E[i].c;
from[E[i].to]=i;
if(!inq[E[i].to]){
Q[++r]=E[i].to;
inq[E[i].to]=;
}
}
}
return d[T]!=INF;
}
void mcf(){
int x=INF;
for(int i=from[T];i;i=from[E[i].from])
x=min(x,E[i].v);
for(int i=from[T];i;i=from[E[i].from]){
E[i].v-=x;
E[i^].v+=x;
ans+=x*E[i].c;
}
// ans+=x*d[t];
}
void init(){
m=getint(); n=getint(); cnt=;
F(i,,n)
F(j,,m) tim[i][j]=getint();
S=; T=n+n*m+;
F(i,,n) add(S,i,,);
F(i,n+,n+n*m) add(i,T,,);
F(i,,n)
F(j,,m)
F(k,,n)//枚举这 第i辆车是第j个人修的第k辆
add(i,j*n+k,,(n-k+)*tim[i][j]);
ans=;
while(spfa()) mcf();
printf("%.2lf\n",double(ans)/n);
}
}G1;
int main(){
#ifndef ONLINE_JUDGE
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
G1.init();
return ;
}
1070: [SCOI2007]修车
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 3044 Solved: 1227
[Submit][Status][Discuss]
Description
同
一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M
位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。 说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
Input
第一行有两个m,n,表示技术人员数与顾客数。 接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。
Output
最小平均等待时间,答案精确到小数点后2位。
Sample Input
3 2
1 4
Sample Output
HINT
数据范围: (2<=M<=9,1<=N<=60), (1<=T<=1000)
Source
【BZOJ】【1070】【SCOI2007】修车的更多相关文章
- BZOJ 1070: [SCOI2007]修车 [最小费用最大流]
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 4936 Solved: 2032[Submit][Status] ...
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3515 Solved: 1411[Submit][Status] ...
- [BZOJ 1070] [SCOI2007] 修车 【费用流】
题目链接:BZOJ - 1070 题目分析 首先想到拆点,把每个技术人员拆成 n 个点,从某个技术人员拆出的第 i 个点,向某辆车连边,表示这是这个技术人员修的倒数第 i 辆车.那么这一次修车对整个答 ...
- BZOJ 1070: [SCOI2007]修车(费用流)
http://www.lydsy.com/JudgeOnline/problem.php?id=1070 题意: 思路: 神奇的构图. 因为排在后面的人需要等待前面的车修好,这里将每个技术人员拆成n个 ...
- bzoj 1070 [SCOI2007]修车——网络流(拆边)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1070 后面还有几辆车在这个人这儿修,自己这辆车的时间对总时间的贡献就要多乘上几倍. 所以可以 ...
- bzoj 1070 [SCOI2007]修车
最小费用最大流. 将每个技术人员拆成车数个点,技术人员i的第j个点代表技术人员i修的倒数第j辆车. 源点向所有技术人员点连一条容量为1费用为0的边. 所有技术人员点向所有车点连边:技术人员i的第j个点 ...
- BZOJ.1070.[SCOI2007]修车(费用流SPFA)
题目链接 /* 神tm看错题*2.. 假如人员i依次维修W1,W2,...,Wn,那么花费的时间是 W1 + W1+W2 + W1+W2+W3... = W1*n + W2*(n-1) + ... + ...
- 【刷题】BZOJ 1070 [SCOI2007]修车
Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的.现在需要安排这M位技术人员所维修的车及顺序,使 ...
- bzoj 1070: [SCOI2007]修车【最小费用最大流】
一开始从客人角度想的,怎么建都不对 从一个修车工所接待的所有顾客花费的总时间来看,设一共有x个人,那么第一个修的对总时间的贡献是x*w1,第二个是(x-1)*w2-以此类推.所以把第i个修车工拆成n组 ...
随机推荐
- Wim技术之Wim文件的制作
背景:操作的镜像文件为win8.1 update的ISO里的Wim文件 1.使用如下命令将支持WimBoot的instal.Wim文件转换成可以支持wimboot启动的映像文件 Dism /Expor ...
- JQuery之append和appendTo的区别,还有js中的appendChild用法
JQuery之append和appendTo的区别 append()前面是要选择的对象,后面是要在对象内插入的元素内容 appendTo()前面是要插入的元素内容且为Jquery对象,而后面是要选择的 ...
- Angular实现数据绑定,它实现原理是什么?
简单的来说,就是给每个需要绑定的元素加上$watcher,缓存下oldValue,然后定时遍历所有的$watcher,比较newValue和oldValue,如果变化了就做更新的操作.
- Silverlight引用WebService时取消对ServiceReferences.ClientConfig文件的依赖
做过Silverlight项目的朋友都知道一般来说我们在Silverlight项目中都需要引用WebService或是WCF,引用的方式是在Visual Studio窗口中通过“添加服务引用”来添加引 ...
- Mac 如何恢复出厂设置
首先将电脑关机然后按电源键启动启动的时候电脑会出现白色什么都没有的界面这时按住 option(alt)键会出现磁盘选择界面然后选择一个叫 Reocorvry10.X.X的硬盘点击那个硬盘按照上面的指示 ...
- android SDK启动的错误
1. AVD Manager.exe : failed to execute tools android.bat 请把AVD Manager.exe复制到跟 SDK Manager.exe的相同目录下 ...
- JS对select动态添加options操作[IE&FireFox兼容]
<select id="ddlResourceType" onchange="getvalue(this)"> </select> 动态 ...
- asp.net2.0 国际化
公司业务需要在国外开展了, 因此以前的系统要做多国语言了, 从网上搜集了好多资料, 最后选择了一个比较简单的方案 1. 打开vs2005, 新建网站, 首先在配置文件中添加配置: <syste ...
- RxJava 平常使用
本文转载自: http://blog.csdn.net/theone10211024/article/details/50435325 一.Scheduler线程切换 这种场景经常会在“后台线程取数据 ...
- dedecms 处理分页样式及去掉分页li
最近装了个织梦dedecmsV5.7版本时,调用分页显示出现的结果出现好几行,怎么也不能在一排显示,找了很多资料,才了解到是由织梦模板中分页加了<Li>列表标签,解决有两种方法,下面将一一 ...