修车 bzoj-1070 SCOI-2007

题目大意:有m个人要修n台车,每个工人修不同的车的时间不同,问将所有的车都修完,最少需要花费的时间。

注释:$2\le m\le 9$,$1\le n \le 60$

想法:想起了那句话...(如果题面复杂,dp状态不可描述,一看数据范围发现才几百,那八成是网络流了),一般这句话都是对的,除了那次在CF上遇到的爆搜.. ...

关于这道题,网上有题解在边上做技巧(完全没明白这样的意义),我的做法时拆点。将每个点拆成n个,然后在这些被拆的点与车之间连边即可,保证每走一条边需要将之后的费用都统计进来。

具体地,将一个j工人拆成n个点,第k个点表示这个工人倒数第k个修车i,那么车i向工人j连一条容量为1,费用为k*w[i][j],表示修自己的车的一个费用,和后面k-1个人等待的费用,就是算自己费用的同时算上别人的费用。注意这样倒着考虑,每个车连的边就只对关于同一个工人但是在他后面修车的有影响。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
#define N 610
#define M 76010
#define INF 0x3f3f3f
long long ans;
struct node{
int x,y,co,next,cap;
}edge[M];
int head[N],dis[N],pre[N];
bool vis[N];
int l,m,n,t,s,w;
void add(int x,int y,int c,int z)
{
l++;
edge[l].x=x;edge[l].y=y;edge[l].co=z;edge[l].cap=c;
edge[l].next=head[x];
head[x]=l;
}
bool spfa()
{
queue<int> q;
for(int i=0;i<=t;i++) {dis[i]=INF;vis[i]=0;}
memset(pre,0,sizeof(pre));
vis[s]=1;dis[s]=0;
q.push(s);
while(!q.empty())
{
int x=q.front();q.pop();
vis[x]=0;
for (int i=head[x];i!=-1;i=edge[i].next)
{
int y=edge[i].y;
if (edge[i].cap && dis[x]+edge[i].co<dis[y])
{
pre[y]=i;
dis[y]=edge[i].co+dis[x];
if (!vis[y]) q.push(y), vis[y]=1;
}
}
}
if (dis[t]<INF) return 1; else return 0;
}
void minf()
{
int i=pre[t],cap=INF;
while(i)
{
cap=min(cap, edge[i].cap);
i=pre[edge[i].x];
}
i=pre[t];
while(i)
{
edge[i].cap-=cap;
edge[i^1].cap+=cap;
ans+=cap*edge[i].co;
i=pre[edge[i].x];
}
}
int main()
{
scanf("%d%d", &m, &n);
l=1;
memset(head,-1,sizeof head);
t=n+m*n+1;s=0;
for(int i=1;i<=n;i++)
{
add(s,i,1,0);
add(i,s,0,0);
for(int j=1;j<=m;j++)
{
scanf("%d", &w);
for(int k=1;k<=n;k++)
{
add(i, j*n+k, 1, k*w);
add(j*n+k, i, 0, -k*w);
}
}
}
for(int j=n+1;j<=m*n+n;j++)
{
add(j,t,1,0);
add(t,j,0,0);
}
ans=0;
while(spfa()) minf();
printf("%.2lf\n", (double)ans / n);
}

  小结:记住一些题目的描述,有利于帮助我门迅速分析出切入点。

[bzoj1070][SCOI2007]修车_费用流的更多相关文章

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

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

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

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

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

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

  4. P2053 [SCOI2007]修车(费用流)

    P2053 [SCOI2007]修车 顾客平均等待的最小时间$=$等待总时间$/n$ 考虑只有1个技术人员时,$n$辆车等待总时间 $A_1+(A_1+A_2)+(A_1+A_2+A_3)+...+\ ...

  5. 【BZOJ1070】修车(费用流)

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

  6. 【洛谷2053】 [SCOI2007]修车(费用流)

    传送门 洛谷 Solution 考虑把每一个修车工人拆成\(n\)个点,那么考虑令\(id(i,j)\)为第\(i\)个工人倒数第\(j\)次修车. 然后就可以直接跑费用流了!!! 代码实现 /* m ...

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

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

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

    题目链接:BZOJ - 1070 题目分析 首先想到拆点,把每个技术人员拆成 n 个点,从某个技术人员拆出的第 i 个点,向某辆车连边,表示这是这个技术人员修的倒数第 i 辆车.那么这一次修车对整个答 ...

  9. 【BZOJ】1070: [SCOI2007]修车(费用流+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1070 好神的题!!!orz 首先我是sb不会拆点..... 首先,每一个技术人员维修车辆都有一个先后 ...

随机推荐

  1. 支撑百亿级应用的 NewSQL

    支撑百亿级应用的 NewSQL https://zhuanlan.zhihu.com/newsql/ 项目背景 初次接触 TiDB,是通过同程网首席架构师王晓波先生的分享,当时同程网正在使开发和数据库 ...

  2. B1232 [Usaco2008Nov]安慰奶牛cheer 最小生成树

    %%%小詹太巨啦!!!我就想直接最小生成树之后建树跑dfs,然后写跪了...然后看小詹博客之后恍然大悟,原来直接把边权改为w * 2 + 两边点权值就行了. 但是还是不对,为什么呢?原来我们起点走了三 ...

  3. [转]深入javascript——原型链和继承

    在上一篇post中,介绍了原型的概念,了解到在javascript中构造函数.原型对象.实例三个好基友之间的关系:每一个构造函数都有一个“守护神”——原型对象,原型对象心里面也存着一个构造函数的“位置 ...

  4. scrollWidth clientWidth offsetWidth

    scrollWidth:对象的实际内容的宽度,不包边线宽度,会随对象中内容超过可视区后而变大.         实际内容+padding                 不包括滚动条 边框client ...

  5. js实现“级联菜单”

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. C++ Rand()各种实现

    参考链接:http://www.cplusplus.com/reference/cstdlib/rand/ 使用实例: v1 = rand() % 100; // v1 in the range 0 ...

  7. cmd 运行 svn 亲测!!!

    如果之前安装了svn客户端,但是一直提示svn停止工作的话就可以用cmd去操作svn更新和提交了:或者可以直接用别的代码IDE(包含svn插件的)去进行svn的操作. 接下来我说说windows如何用 ...

  8. google浏览器 打印A4 最大宽度和高度px

    width: 1563px;(max) + = 分页了 + = 分页了 + = 没有分页 / ViewBag.results[].Count)); <td width="15%&quo ...

  9. vue向数组中动态添加数据

    vue中数据更新通过v-model实现,向数组中添加数据通过push()实现,向shortcuts数组中动态添加newShortcut对象中的title和action this.shortcuts.p ...

  10. luogu P2422 良好的感觉 单调栈

    Code: #include<bits/stdc++.h> #define maxn 1000000 #define ll long long using namespace std; v ...