http://poj.org/problem?id=3686

题目大意:

有n个订单m个厂子,第i个订单在第j个厂子所需时间为zij,一个厂子做一个订单时不能做其他的订单。

求订单平均时间最小值。

————————————

这题最开始样例都没推出来让我很绝望,这里解释一下样例。

第一个样例可以1订单做1时间,2订单做2时间(自己1时间+1订单的时间),3订单做3时间,总共6时间/3=2.

接下来考虑建图。

类似二分图+费用流的想法,边的容量为1,费用为时间。

于是这题的关键在于如何让厂子处理多个订单——明显是拆点,怎么拆是关键。

举个例子,假设这个厂子要处理abc三个订单,那么花费总时间就是:

ta+ta+tb+ta+tb+tc=3ta+2tb+1tc。

四个订单就是4ta+3tb+2tc+1td……

我们成功把时间长短变成了订单接的先后顺序。

于是变成:

将厂子拆点成二元组(i,j),其中i为厂子,j为该厂子已经接了(j-1)个订单。

对于k的订单在i厂子花t时间就可以变成:

k连(i,j),容量为1,费用为t*j。

接下来就是板子的活了。

(poj开%f,开%lf会WA……)

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cctype>
using namespace std;
typedef long long ll;
const int INF=1e9;
const int N=;
const int M=;
const int P=N+M*N+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int nxt;
int to;
int w;
int b;
}edge[(N+N*N*M+N*M)*];
int head[P],cnt=-;
void add(int u,int v,int w,int b){
cnt++;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].b=b;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
int dis[P];
bool vis[P];
inline bool spfa(int s,int t,int n){
deque<int>q;
memset(vis,,sizeof(vis));
for(int i=;i<=n;i++)dis[i]=INF;
dis[t]=;q.push_back(t);vis[t]=;
while(!q.empty()){
int u=q.front();
q.pop_front();vis[u]=;
for(int i=head[u];i!=-;i=edge[i].nxt){
int v=edge[i].to;
int b=edge[i].b;
if(edge[i^].w&&dis[v]>dis[u]-b){
dis[v]=dis[u]-b;
if(!vis[v]){
vis[v]=;
if(!q.empty()&&dis[v]<dis[q.front()]){
q.push_front(v);
}else{
q.push_back(v);
}
}
}
}
}
return dis[s]<INF;
}
int ans=;
int dfs(int u,int flow,int m){
if(u==m){
vis[m]=;
return flow;
}
int res=,delta;
vis[u]=;
for(int e=head[u];e!=-;e=edge[e].nxt){
int v=edge[e].to;
int b=edge[e].b;
if(!vis[v]&&edge[e].w&&dis[u]-b==dis[v]){
delta=dfs(v,min(edge[e].w,flow-res),m);
if(delta){
edge[e].w-=delta;
edge[e^].w+=delta;
res+=delta;
ans+=delta*b;
if(res==flow)break;
}
}
}
return res;
}
inline int costflow(int S,int T,int n){
while(spfa(S,T,n)){
do{
memset(vis,,sizeof(vis));
dfs(S,INF,T);
}while(vis[T]);
}
return ans;
}
void restart(){
memset(head,-,sizeof(head));
cnt=-;
ans=;
return;
}
int main(){
int t=read();
while(t--){
restart();
int n=read();
int m=read();
int S=n+m*n+,T=n+m*n+;
for(int i=;i<=n;i++){
add(S,i,,);
add(i,S,,);
for(int j=;j<=m;j++){
int z=read();
for(int k=;k<=n;k++){
int p=j*n+k;
add(i,p,,z*k);
add(p,i,,-z*k);
}
}
}
for(int i=n+;i<=n+n*m;i++){
add(i,T,,);
add(T,i,,);
}
printf("%.6f\n",costflow(S,T,n+m*n+)*1.0/n);
}
return ;
}

POJ3686:The Windy's——题解的更多相关文章

  1. POJ3686 The Windy's 【费用流】*

    POJ3686 The Windy’s Description The Windy’s is a world famous toy factory that owns M top-class work ...

  2. BZOJ1026:[SCOI2009]windy数——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026 Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2 ...

  3. C++ 洛谷 P2657 [SCOI2009]windy数 题解

    P2657 [SCOI2009]windy数 同步数位DP 这题还是很简单的啦(差点没做出来 个位打表大佬请离开(包括记搜),我这里讲的是DP!!! 首先Cal(b+1)-Cal(a),大家都懂吧(算 ...

  4. POJ-3686 The Windy's KM算法 拆点题

    参考:https://blog.csdn.net/sr_19930829/article/details/40680053 题意: 有n个订单,m个工厂,第i个订单在第j个工厂生产的时间为t[i][j ...

  5. POJ3686 The Windy's(最小费用最大流)

    题目大概说要用m个工厂生产n个玩具,第i个玩具在第j个工厂生产要Zij的时间,一个工厂同一时间只能生成一个玩具,问最少的用时. 这题建的图不是很直观.. 源点向玩具连容量1费用0的边 将每个工厂拆成n ...

  6. POJ3686 The Windy's

    嘟嘟嘟 刚做费用流,思路完全不对呀-- 应该这么想(应该说敢这么想):这道题的关键在于怎么体现这个玩具是第几个加工的,只有这才能求出他的加工时间(因为加工时间包括等待时间). 但等待时间不好求,因此要 ...

  7. [poj3686]The Windy's(费用流)

    题目大意: 解题关键:指派问题,待更. #include<cstdio> #include<cstring> #include<algorithm> #includ ...

  8. 洛谷P2657 [SCOI2009]windy数 题解 数位DP

    题目链接:https://www.luogu.com.cn/problem/P2657 题目大意:找区间 \([A,B]\) 范围内 不含前导零 且 相邻两个数字之差至少为2 的正整数的个数. 题目分 ...

  9. luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索

    题目链接 luogu P2657 [SCOI2009]windy数 题解 我有了一种所有数位dp都能用记忆话搜索水的错觉 代码 #include<cstdio> #include<a ...

随机推荐

  1. nodeJs 安装 npm nodeModules package.json

    Nodejs   1.安装nodejs 从nodejs官网下载最新版本的node,设置环境变量这样就可以在cmd下直接用命令行操作npm 环境变量:path  d:/nodejs 查看本机node及n ...

  2. 「Python」Convert map object to numpy array in python 3

    转自Stackoverflow.备忘用. Question In Python 2 I could do the following: import numpy as np f = lambda x: ...

  3. Qt-QML-Repeater-导航条

    上篇文章中,我写了一个自己的Button,也就是美化了一下QML自带的Button 就是上面的这个,剩下的就是放三张图片在上面就可以了,当然了,这个Button在后期,还是会加入更让多的美化,比如,可 ...

  4. Java开发工程师(Web方向) - 03.数据库开发 - 第4章.事务

    第4章--事务 事务原理与开发 事务Transaction: 什么是事务? 事务是并发控制的基本单位,指作为单个逻辑工作单元执行的一系列操作,且逻辑工作单元需满足ACID特性. i.e. 银行转账:开 ...

  5. git 从头开始

    下载安装git 打开git,输入以下命令,引号内的为你自己的名字和邮箱 git config --global user.name "Your Name"git config -- ...

  6. [Clr via C#读书笔记]Cp9参数

    Cp9参数 可选参数和命名参数 参数设置了默认值(设置要从右到左,有默认值的参数必须放在没有默认值的参数的后面,默认值必须是常量),就可以使用可选参数和命名参数了.向方法传递实参的时候,编译器按照从左 ...

  7. ElasticSearch 论坛搜索查询语句

    概述 研究论坛搜索如何综合时间和TF/IDF权重. 自定义权重计算的效率问题 数据结构 假设有一个论坛的搜索 字段包括: subject:标题 message:内容 dateline:发布时间 tag ...

  8. 在 CentOS 下手工安装 Docker v1.1x

    Docker在 centos 6.x 下面默认最新的版本是1.7, 然而这个并不符合我的实际需求, 尤其我需要 docker-compose 来作为编配工具部署swarm, 所以我只有手工安装了. 首 ...

  9. 关于ES6-{块级作用域 let const 解构赋值 数组 字符串 函数的扩展 箭头函数}

    关于ES6 块级作用域 任何一对花括号({})中的语句集都属于一个块,在块中声明的变量在代码块外都是不可访问的,称之为块级作用域,ES5以前没有块级作用域 let let 是ES6新增的声明变量的一种 ...

  10. python异步初步窥探

    1.异步之难:因为其执行吮吸不可预料,当下正要发生什么事件不可预料.        程序下一步行为往往依赖上一步值执行结果,如何知晓上次异步调用已完成并获取结果,        回调成了必然选择,那又 ...