【BZOJ1070】[SCOI2007]修车

题面

以后要多写题面flag

题目描述

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

客平均等待的时间最小。

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

输入格式

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

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

输出格式

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

样例

输入样例

2 2
3 2
1 4

输出样例

1.50

说明

\((2\leq M\leq 9,1\leq N\leq 60), (1\leq T\leq 1000)\)

题解

设某个技术人员的修车序列为\(a_1,a_2...a_n\)

则这个人所用时间

\[\sum_{i=1}^nT_{a_i}*(n-i+1)\\
\Leftrightarrow n*T_{a_1}+(n-1)*T_{a_2}+...+1*T_{a_n}
\]

这样的话,我们可以将一次在第\(k\)次修决策化为一次

费用为\(T_{i,j}*k\)的决策

因此我们可以得到一个决策集合:决策\(\left(i,j,k\right)=T\left(i,j\right)\ast k\)表示“把第i辆车让第j个人在“需要消耗k次时间”的那个个位置修”

那实际上我们就是对于每个\(i\)选取一个这样的决策,同时这个决策的\(\left(j,k\right)\)不能相同

最后怎么办呢?

建一个\(n*m\)的决策图,表示决策\(j,k\)

再建\(n\)个车的点,表示那辆车

再对于决策图的每一层,向车\(i\)连\(Ti,j*层数\)费用,容量为\(1\)的边

最后连\(S,T\)即可

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX_N = 300;
const int INF = 1e9;
struct Graph { int to, cap, cost, next; } e[MAX_N * MAX_N << 2];
int fir[MAX_N * MAX_N], e_cnt, V;
void clearGraph() { memset(fir, -1, sizeof(fir)); e_cnt = 0; }
void Add_Edge(int u, int v, int cap, int cost) {
e[e_cnt] = (Graph){v, cap, cost, fir[u]}; fir[u] = e_cnt++;
e[e_cnt] = (Graph){u, 0, -cost, fir[v]}; fir[v] = e_cnt++;
}
int dis[MAX_N * MAX_N], preve[MAX_N * MAX_N], prevv[MAX_N * MAX_N];
bool inq[MAX_N * MAX_N];
int min_cost_flow(int s, int t) {
static queue<int> que; int res = 0;
while (1) {
fill(&dis[0], &dis[V + 1], INF);
fill(&inq[0], &inq[V + 1], 0);
que.push(s), dis[s] = 0, inq[s] = 1;
while (!que.empty()) {
int x = que.front(); que.pop();
for (int i = fir[x]; ~i; i = e[i].next) {
int v = e[i].to;
if (dis[x] + e[i].cost < dis[v] && e[i].cap > 0) {
dis[v] = dis[x] + e[i].cost;
preve[v] = i, prevv[v] = x;
if (!inq[v]) que.push(v), inq[v] = 1;
}
}
inq[x] = 0;
}
if (dis[t] == INF) return res;
int d = INF;
for (int x = t; x != s; x = prevv[x]) d = min(d, e[preve[x]].cap);
res += dis[t] * d;
for (int x = t; x != s; x = prevv[x]) {
e[preve[x]].cap -= d;
e[preve[x] ^ 1].cap += d;
}
}
}
int N, M, id[MAX_N][MAX_N], T[MAX_N][MAX_N];
int main () {
clearGraph();
cin >> M >> N; int s = 0, t, tot = 0;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) id[i][j] = ++tot;
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) cin >> T[i][j];
V = t = (N + 1) * M + 1;
for (int i = 1; i <= N; i++) Add_Edge(s, i, 1, 0);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++) Add_Edge(N + id[i][j], t, 1, 0);
for (int i = 1; i <= N; i++)
for (int j = 1; j <= M; j++)
for (int k = 1; k <= N; k++)
Add_Edge(i, N + id[k][j], 1, T[i][j] * k);
printf("%0.2lf\n", 1.0 * min_cost_flow(s, t) / N);
return 0;
}

【BZOJ1070】[SCOI2007]修车的更多相关文章

  1. [bzoj1070][SCOI2007]修车_费用流

    修车 bzoj-1070 SCOI-2007 题目大意:有m个人要修n台车,每个工人修不同的车的时间不同,问将所有的车都修完,最少需要花费的时间. 注释:$2\le m\le 9$,$1\le n \ ...

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

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

  3. bzoj1070: [SCOI2007]修车(费用流)

    1070: [SCOI2007]修车 题目:传送门 题解: 一道挺简单的费用流吧...胡乱建模走起 贴个代码... #include<cstdio> #include<cstring ...

  4. BZOJ1070: [SCOI2007]修车(最小费用最大流,思维)

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

  5. BZOJ1070 [SCOI2007]修车

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  6. [BZOJ1070][SCOI2007]修车(最小费用最大流)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1070 分析: 把每个工人拆成N个点.记为A[i,j]表示第i个工人修倒数第j辆车. 每 ...

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

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

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

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

  9. BZOJ1070[SCOI2007]修车——最小费用最大流

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

  10. 2018.10.13 bzoj1070: [SCOI2007]修车(费用流)

    传送门 费用流经典题目. 自我感觉跟TheWindy′sThe Windy'sTheWindy′s很像. 利用费用提前计算的思想来建图就行了. 代码: #include<bits/stdc++. ...

随机推荐

  1. 能力成熟度模型(CMM)

    能力等级 特点 关键过程 第一级 基本级 软件过程是混乱无序的,对过程几乎没有定义,成功依靠的是个人的才能和经验,管理方式属于反应式   第二级 重复级 建立了基本的项目管理来跟踪进度.费用和功能特征 ...

  2. 标准的Flask启动文件

    最近有一些同学问了我一些项目结构的问题 所以今天给大家专门讲解 解耦后的项目 目录我会分为两种方式:一种是普通解耦 一种是多mvc解耦 首先 我没先建立我们程序的文件夹并且在这个文件夹内写一个和这个文 ...

  3. 可以触发点击事件并变色的UILabel

    可以触发点击事件并变色的UILabel 谁说UILabel不能够当做button处理点击事件呢?今天,笔者就像大家提供一个改造过的,能够触发点击事件并变色的UILabel:) 效果图: 还能当做计时器 ...

  4. Redis学习---Redis的免密操作

    Redis的免密操作 问题解决[方式一]:当前这种linux配置redis密码的方法是一种临时的,如果redis重启之后密码就会失效 1.首先进入redis,如果没有开启redis则需要先开启: [r ...

  5. ZT CSDN 如何以最快的速度计算出一个二进制数中1的个数? [

    一道算法面试题:如何以最快的速度计算出一个二进制数中1的个数? [问题点数:10分,结帖人weicai_chen] 收藏 weicai_chen weicai_chen 等级: 结帖率:95.12% ...

  6. Eclipse解决运行、启动缓慢问题思路

    我的Eclipse近几天运行时速度奇慢,具体表现为: 1.只要ECLIPSE启动后,硬盘灯就狂闪,不停的读盘: 2.发布TOMCAT经常在0%: 3.偶尔CPU占满: 网上讲优化的文章无数,但是总是有 ...

  7. IDEA 使用技巧 Update

    IDEA使用起来和Eclipse很大区别. 1.快捷键. 因为一个个熟悉起来费时间,就直接在Preferences—keymap里选择了Eclipse OS X,这样快捷键就转换到了Mac下Eclip ...

  8. IDEA使用心得整理

    [演出模式] 我们可以使用[Presentation Mode],将IDEA弄到最大,可以让你只关注一个类里面的代码,进行毫无干扰的coding. 可以使用Alt+V快捷键,弹出View视图,然后选择 ...

  9. java.sql.SQLException: Incorrect string value: '\xE5\xB0‘

    mysql插入中文字符报java.sql.SQLException: Incorrect string value: '\xE5\xB0‘ #原因:由于默认情况下,mysql的字符集是latin1(I ...

  10. linux用户相关及/etc/passed,/etc/group,/etc/shadow

    useradd:新建用户 usermod:修改用户相关信息 userdel:删除用户分(-r选项) 组的操作与用户的操作类似 选项 userdel相关选项: -f:强制删除用户,即使用户已登录 -r: ...