【BZOJ】1070: [SCOI2007]修车
1070: [SCOI2007]修车
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)
思路:开始以为排序之后模拟贪心,但是车的数量太多...每次对于一个工人来说,并不是直接按照他修理车的最短时间给他分配车的,还要看里面各种..修车时间差与等待总时间等因素;所以要用到网络流构图,让计算机不断的调整选择方案(增广路模拟);即最小费用最大流问题;
暴力构图:每个工人可能修理的车的数量即为车的数量,并且每次修理车的时间并不只是输入的时间,因为对于同一个工人来说其前面修理的车的时间会累加到后面修车的时间里面;但是一般这样前面对后面产生的次数影响,并不是对当前的车去看它前面修了哪些车,然后把这些车的总时间加上自己的时间代价的,因为这样还要不断记录与修改修车的顺序。。与其后面每次来找前面的麻烦。。还不如前面修理的时候直接计算出对后面的影响~~ 即该车是同一个工人倒数第k次修的,那么这辆车的总代价就是k*time[i][j];这样就有了暴力拆点的依据了~~
暴力拆点:把每个工人拆成m个点,第k个点表示是倒数第k次修的该车,至于该车就修改每辆车与n*m个点连边,边的容量为1,表示只修一次。费用为time[i]][j]*k;至于与超级源点和汇点连边时,cap为1,但是费用记得要记为0;这样直接跑最大流即可;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define MS0(a) memset((a),0,sizeof(a))
#define MSi(a) memset((a),0x3f,sizeof(a))
#define MS1(a) memset((a),-1,sizeof(a))
#define inf 0x3f3f3f3f
const int T = ;
const int M = ;
const int N = ;
int tot = ,head[N];
struct edge{
int from,to,Next,cap,cost;
}e[M<<];
void ins(int u,int v,int cap,int cost)
{
e[++tot].Next = head[u];// tot从2开始,之后增广边还是可以异或~~并且head并不需要设为-1.
e[tot].from = u, e[tot].to = v;
e[tot].cap = cap; e[tot].cost = cost;
head[u] = tot;
}
void insert(int u,int v,int cap,int cost)//把cap当成费用;之后增广路中只是改变flow;
{
ins(u,v,cap,cost);ins(v,u,,-cost);
}
int t[][],dis[N],vis[N],p[N];
queue<int> que;
int spfa()
{
MSi(dis);
que.push();
p[] = ;dis[] = ;
while(!que.empty()){
int u = que.front();que.pop();
vis[u] = ;
for(int d = head[u];d ;d = e[d].Next){
int v = e[d].to;
if(e[d].cap && dis[v] > dis[u] + e[d].cost){
dis[v] = dis[u]+e[d].cost;
p[v] = d;
if(!vis[v]){
que.push(v);
vis[v] = ;
}
}
}
}
if(dis[T] == inf) return ;
return ;
}
int ans;
int mcf()
{
int v = inf;
for(int d = p[T];d;d = p[e[d].from])
v = min(v,e[d].cap);
for(int d = p[T];d;d = p[e[d].from]){
e[d].cap -= v; e[d^].cap += v;
ans += e[d].cost;
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i = ;i <= m;i++)
for(int j = ;j <= n;j++)
scanf("%d",&t[i][j]);
for(int i = ;i <= n;i++)
for(int j = ;j <= m;j++)
insert(,(i-)*m+j,,);
for(int i = n*m+;i <= n*m+m;i++)
insert(i,T,,);
for(int i = ;i <= n;i++)
for(int j = ;j <= m;j++)//第i个工人修的倒数第j辆车;
for(int k = ;k <= m;k++)
insert((i-)*m+j,n*m+k,,t[k][i]*j);
while(spfa()) mcf();
printf("%.2f",.*ans/m);
}
【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组 ...
随机推荐
- linux上安装ftp
1.安装 rpm -ivh vsftpd-2.2.2-11.el6_4.1.x86_64.rpm 2.启动 service vsftpd start 3.连接 windows 命令行输入 ftp ww ...
- ASP.NET 不同页面之间传值
不同页面之间如何传值?我们假设A和B两个页面,A是传递,B是接收. 下面学习4种方式: 通过URL链接地址传递 POST方式传递 Session方式传递 Application方式传递 1. 通过UR ...
- Android更改imagebutton为纯色方法
我的imagebutton所用的背景png图片是灰色的,但是我想让他显示出来是白色的按钮,如果用ps去一个个填充不太现实,那有没有什么办法去通过xml里的属性改变背景颜色呢? 一开始我用了网上的方法 ...
- Android_Handler
xml文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:t ...
- Callable、Future和FutureTask使用说明
普通的创建线程,一种是直接继承Thread,另外一种就是实现Runnable接口.但是这两种都无法在执行完任务之后获取执行结果,Callable.Future就提供了这样的便利. Future的方 ...
- myeclipse使用太卡问题
最近写html文件,修改内容时,就会反应好长时间,太卡. 原因:没修改一次,它就会自动校验. 解决方法:window——preferences——Editors——Text Editors ——spe ...
- matlab中num2str的应用
在求导数,积分,方程的过程中,难免会遇到一些参数要随着情况有点变化,这时,你就需要能够动态的表示出你的表达式,Num2str函数是一个相当有用的函数,一般配合[]连接符使用,下面将我接触到的一些用法写 ...
- how to learn algorithms(ZAC)
(这一篇觉得写得很棒,故拷过来以便慢慢看,细细体会,详情请访问http://blog.csdn.net/shenmen123456/article/details/6575647) 第一阶段:练经典常 ...
- [问题] PHP接收Request payload传递过来的参数
在使用Apidoc的时候,有一个配置参数是 @apiSampleRequest http://localhost/api 在测试时,发现发送的参数是Request payload的,而PHP中使用的A ...
- mysql同时向一个表中插入多条数据问题!!见详细
INSERT INTO `表名` (`字段1`,`字段2`,`字段3`,`字段4`) values ('数组1数据1','数组1数据2','数组1数据3','数组1数据4'), ('数组2数据1',' ...