P2053 [SCOI2007]修车 费用流
$ \color{#0066ff}{ 题目描述 }$
同一时刻有N位车主带着他们的爱车来到了汽车维修中心。维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的。现在需要安排这M位技术人员所维修的车及顺序,使得顾客平均等待的时间最小。
说明:顾客的等待时间是指从他把车送至维修中心到维修完毕所用的时间。
\(\color{#0066ff}{输入格式}\)
第一行有两个数M,N,表示技术人员数与顾客数。
接下来n行,每行m个整数。第i+1行第j个数表示第j位技术人员维修第i辆车需要用的时间T。
\(\color{#0066ff}{输出格式}\)
最小平均等待时间,答案精确到小数点后2位。
\(\color{#0066ff}{输入样例}\)
2 2
3 2
1 4
\(\color{#0066ff}{输出样例}\)
1.50
\(\color{#0066ff}{数据范围与提示}\)
(2<=M<=9,1<=N<=60), (1<=T<=1000)
\(\color{#0066ff}{题解}\)
这种对应关系还有数据范围,显然就是费用流了
现在的问题是怎么建边
发现,每辆车的等待时间跟前面修车人所修的车有关
假设某人修了10辆车
那么他修第一辆的时候,后面9人都等了这个时间,也就是贡献+=9倍的这个时间
因此我们单独考虑这个人修的每一辆车对时间的贡献
把每个人都拆成n个点
对于一个人的第k个点,连向它的车代表他倒数第k次修它
也就是连T*k的边权,倒数第k次修它,那么后面k辆车就会产生这么多贡献
跑一遍费用流即可(zkw大法好)
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
LL in() {
char ch; LL x = 0, f = 1;
while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
return x * f;
}
const int maxn = 1e5 + 10;
const int inf = 0x7fffffff;
struct node {
int to, can, dis;
node *nxt, *rev;
node(int to = 0, int can = 0, int dis = 0, node *nxt = NULL): to(to), can(can), dis(dis), nxt(nxt) {
rev = NULL;
}
};
node *head[maxn], *cur[maxn];
bool vis[maxn];
int n, m, s, t;
int dis[maxn];
void add(int from, int to, int can, int dis) {
head[from] = new node(to, can, dis, head[from]);
}
void link(int from, int to, int can, int dis) {
add(from, to, can, dis);
add(to, from, 0, -dis);
head[from]->rev = head[to];
head[to]->rev = head[from];
}
bool spfa() {
std::queue<int> q;
for(int i = s; i <= t; i++) dis[i] = inf, vis[i] = false;
q.push(t);
dis[t] = 0;
while(!q.empty()) {
int tp = q.front(); q.pop();
vis[tp] = false;
for(node *i = head[tp]; i; i = i->nxt) {
if(dis[i->to] > dis[tp] - i->dis && i->rev->can) {
dis[i->to] = dis[tp] - i->dis;
if(!vis[i->to]) {
q.push(i->to);
vis[i->to] = true;
}
}
}
}
return dis[s] != inf;
}
int dfs(int x, int change) {
if(x == t || !change) return change;
int flow = 0, ls;
vis[x] = true;
for(node *i = head[x]; i; i = i->nxt) {
if(!vis[i->to] && dis[i->to] == dis[x] - i->dis && (ls = dfs(i->to, std::min(change, i->can)))) {
flow += ls;
change -= ls;
i->can -= ls;
i->rev->can += ls;
if(!change) break;
}
}
return flow;
}
int zkw() {
int cost = 0;
while(spfa()) {
vis[t] = true;
while(vis[t]) {
for(int i = s; i <= t; i++) vis[i] = false;
cost += dis[s] * dfs(s, inf);
}
}
return cost;
}
int main() {
m = in(), n = in(), s = 0, t = m * n + n + 1;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
link(s, (i - 1) * n + j, 1, 0);
for(int i = 1; i <= n; i++) link(m * n + i, t, 1, 0);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
int x = in();
for(int k = 1; k <= n; k++) link((j - 1) * n + k, n * m + i, 1, k * x);
}
printf("%.2f\n", (double)zkw() / n);
return 0;
}
P2053 [SCOI2007]修车 费用流的更多相关文章
- bzoj 1070: [SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2785 Solved: 1110[Submit][Status] ...
- [BZOJ1070][SCOI2007]修车 费用流
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 6209 Solved: 2641[Submit][Status] ...
- 【BZOJ1070】[SCOI2007]修车 费用流
[BZOJ1070][SCOI2007]修车 Description 同一时刻有N位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不同的技术人员对不同的车进行维修所用的时间是不同的. ...
- [bzoj1070][SCOI2007]修车——费用流
题目大意: 传送门 题解: 本题和(POJ3686)[http://poj.org/problem?id=3686]一题一模一样,而且还是数据缩小以后的弱化版QAQ,<挑战程序设计竞赛>一 ...
- [BZOJ1070] [SCOI2007] 修车 (费用流 & 动态加边)
Description 同一时刻有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) + ... + ...
随机推荐
- leetcode539
public class Solution { public int FindMinDifference(IList<string> timePoints) { * ]; foreach ...
- hive自带的字符串函数
1. 字符串长度函数:length 语法: length(string A) 返回值: int 说明:返回字符串A的长度 举例: hive> select length('abcedfg') f ...
- Oracle与SQL Server实现表数据同步
将SQLServer2008中的某些表同步到Oracle数据库中,不同数据库类型之间的数据同步我们可以使用链接服务器和SQLAgent来实现. 实例1:SQLServer2008有一个表employ_ ...
- mysql主从延迟
1. MySQL数据库主从同步延迟原理.要说延时原理,得从mysql的数据库主从复制原理说起,mysql的主从复制都是单线程的操作,主 库对所有DDL和DML产生binlog,binlog是顺序写,所 ...
- mysql外键约束总结
总结三种MySQL外键约束方式 如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是 ...
- mongo 修改器 $inc/$set/$unset/$pop/$push/$pull/$addToSet
mongo $inc 可以对集合里面的某些值是数字的增减.看代码 $set 可以进行修改,并且不存在的时候默认添加. 同时还能该变数据的类型. 还可以该变内嵌元素的值 用.调用 $unset 删除 ...
- iOS与HTML5交互方法总结(修正)
摘要 看了不少别人写的博客或者论坛,关于iOS与HTML5交互方法大概主要有5种方式: 1. 利用WKWebView进行交互(系统API) 2. 利用UIWebView进行交互(系统API) 3. 苹 ...
- 189. Rotate Array 从右边开始翻转数组
[抄题]: Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the ...
- OpenCV 2.4.13 installed in Ubuntu 14 and CMakeLists Demo
1. 配置编译器环境 [compiler] sudo apt-get install build-essential 2. 安装OpenCV的依赖包 [required] -dev pkg-confi ...
- xamarin.droid自己的示例工程有些都装不上模拟器,是因为它的architectures选项没设对
也许是版本更迭导致的,有些老工程的architectures不对,如果x86不勾的话,是不能在genymotion的模拟器上跑的.