题目链接:BZOJ - 1070

题目分析

首先想到拆点,把每个技术人员拆成 n 个点,从某个技术人员拆出的第 i 个点,向某辆车连边,表示这是这个技术人员修的倒数第 i 辆车。那么这一次修车对整个答案的贡献就是,i * Time[j][k]。 j 是车的编号,k 是技术人员编号。因为这辆车以及之后这个人要修的车的等待时间都增加了 Time[j][k], 所以包括这辆车在内一共有 i 辆车的等待时间加上了这次修车的时间。这样倒着考虑就可以用边的费用很简便的表示修车使所有人增加的时间了。从 S 到所有技术人员拆出的所有点连边,容量 1 , 费用 0 ;从每辆车向 T 连边,容量 1 ,费用 0 。

最后跑一边最小费用最大流就是所有车等待时间的和。

代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue> using namespace std; const int MaxN = 1000 + 5, MaxM = 100000 + 5, INF = 999999999; int n, m, S, T, Ans;
int Time[60 + 5][9 + 5], d[MaxN]; bool Used[MaxN]; queue<int> Q; inline int gmin(int a, int b) {return a < b ? a : b;}
inline int gmax(int a, int b) {return a > b ? a : b;} struct Edge
{
int u, v, w, Cost;
Edge *Next, *Other;
} E[MaxM], *P = E, *Point[MaxN], *Pre[MaxN]; inline void AddEdge(int x, int y, int z, int Ct) {
Edge *Q = ++P; ++P;
P -> u = x; P -> v = y; P -> w = z; P -> Cost = Ct;
P -> Next = Point[x]; Point[x] = P; P -> Other = Q;
Q -> u = y; Q -> v = x; Q -> w = 0; Q -> Cost = -Ct;
Q -> Next = Point[y]; Point[y] = Q; Q -> Other = P;
} bool Found() {
memset(d, 0x7f, sizeof(d));
memset(Used, 0, sizeof(Used));
d[S] = 0; Used[S] = true; Q.push(S);
while (!Q.empty()) {
int x = Q.front();
Used[x] = false;
Q.pop();
for (Edge *j = Point[x]; j; j = j -> Next) {
if (j -> w && d[j -> v] > d[x] + j -> Cost) {
d[j -> v] = d[x] + j -> Cost;
Pre[j -> v] = j;
if (!Used[j -> v]) {
Used[j -> v] = true;
Q.push(j -> v);
}
}
}
}
if (d[T] < INF) return true;
return false;
} void Augment() {
int Flow;
Flow = INF;
for (Edge *j = Pre[T]; j; j = Pre[j -> u]) Flow = gmin(Flow, j -> w);
for (Edge *j = Pre[T]; j; j = Pre[j -> u]) {
j -> w -= Flow;
j -> Other -> w += Flow;
}
Ans += Flow * d[T];
} int main()
{
scanf("%d%d", &m, &n);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
scanf("%d", &Time[i][j]);
}
}
S = n * m + n + 1; T = S + 1;
for (int i = 1; i <= n * m; ++i) AddEdge(S, i, 1, 0);
for (int i = n * m + 1; i <= n * m + n; ++i) AddEdge(i, T, 1, 0);
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
for (int k = 1; k <= n; ++k) {
AddEdge((i - 1) * n + j, n * m + k, 1, j * Time[k][i]);
}
}
}
Ans = 0;
while (Found()) Augment();
printf("%.2lf\n", (double)Ans / (double)n);
return 0;
}

  

[BZOJ 1070] [SCOI2007] 修车 【费用流】的更多相关文章

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

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

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

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

  3. BZOJ 1070: [SCOI2007]修车 [最小费用最大流]

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

  4. bzoj 1070 [SCOI2007]修车(最小费用最大流)

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

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

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

  6. BZOJ 1070 拆点 费用流

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

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

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

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

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

  9. bzoj 1070 [SCOI2007]修车——网络流(拆边)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1070 后面还有几辆车在这个人这儿修,自己这辆车的时间对总时间的贡献就要多乘上几倍. 所以可以 ...

随机推荐

  1. ssss

    18:15 2013/6/18 未结束的事情1 应用API接口切换2 03in.com 项目管理授权 软件中不成功3 党校考核时间 段列出所有 10:51 2013/6/20 daili 应用修改1 ...

  2. [MODx] Solve cannot upload large file

    If you also run into this problem, dont' worry, here is the solution for you. First: In Modx, go &qu ...

  3. Android(java)学习笔记201:网络图片浏览器的实现(ANR)

    1.我们在Android下,实现使用http协议进行网络通信,请求网络数据.这里是获取网络上的图片信息,让它可以显示在手机上: 但是我们这个手机连接网络是很费时间,如果我们在主线程(UI线程)中写这个 ...

  4. instanceof的用法②

    其实这个问题以前也困扰过我.我个人理解的一个应用场合就是,当你拿到一个对象的引用时(例如参数), 你可能需要判断这个引用真正指向的类.所以你需要从该类继承树的最底层开始,使用instanceof操作符 ...

  5. SQL server 如何附加、还原、分离、备份数据库文件

    No1 : 附加 No2 : 还原            一.(需要 .bak文件)首先建立一个数据库,数据库名称与你的.bak文件名要相同. 当然.这时候的这个数据库还是空的,需要还原回去数据.右键 ...

  6. maclean-【性能调优】Oracle AWR报告指标全解析 学习笔记

    原文链接:http://www.askmaclean.com/archives/performance-tuning-oracle-awr.html AWR小技巧 手动执行一个快照: Exec dbm ...

  7. iOS 原生二维码扫描(可限制扫描区域)

    篇文章的主要原因不是展示如何使用  AVFoundation 来进行二维码扫描,更主要的是限制扫描二维码的范围.(因为默认的是全屏扫描) 项目遇到扫描二维码的功能需求,这里我放弃了使用三方库,而采用了 ...

  8. iOS 延迟执行代码

    //延迟执行 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)),dispatch_get_main ...

  9. 求fibonacci数列 java

    java 和 c 差不多.但是java可以根据需求定义数组. 我还不会java的函数调用,所以用数组的方法. import java.util.Scanner; public class fibon{ ...

  10. gSoap实现ONVIF中xsd__anyType到具体结构类型的转换

    上一篇文章已经粗略计划要讨论gsoap关于序列化/解析编程. 本文则阐述一下关于gsoap生成代码的一些重要特征方法及使用.如题,下我们从ONVIF生成的C码中,挑选简单的一个类型来试验一下与xsd_ ...