POJ 3686 *最小费用流-转化成普通指派问题)
题意】
有N个订单和M个机器,给出第i个订单在第j个机器完成的时间Mij,每台机器同一时刻只能处理一个订单,机器必须完整地完成一个订单后才能接着完成下一个订单。问N个订单完成时间的平均值最少为多少。
分析 :
最小费用最大流
如果每个工厂只能完成一个订单的话,那就是指派问题了。跑一遍最小费用流即可。但是题目每个工厂可能完成多个。
所以需要将其拆点使得每个工厂只能完成一个订单,进而转换成指派问题。对一个工厂来说,如果每个订单都在这个
工厂完成的话,那么时间为T=t1 + (t1+t2) + (t1+t2+t3) +... = n*t1 + (n-1)*t2 + (n-2)*t3 + ...就可将其看成
是n个只能完成一个订单的工厂只不过它们需要乘于花费的1到N倍。
#include <iostream>
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring> using namespace std;
const int maxn = ;
const int INF = 0x3f3f3f3f; typedef pair<int,int> P;
struct Edge
{
int to, cap, cost, rev;
Edge(int to_, int cap_, int cost_, int rev_):to(to_),cap(cap_),cost(cost_),rev(rev_){}
}; vector<Edge> G[maxn];
int V, n, m, relation[][];
int h[maxn], dist[maxn], prevv[maxn], preve[maxn]; void add_edge(int from, int to, int cap, int cost)
{
G[from].push_back(Edge(to, cap, cost, G[to].size()));
G[to].push_back(Edge(from, , -cost, G[from].size()-));
} int min_cost_flow(int s, int t, int f)
{
int res = ;
memset(h, , sizeof(h));
while(f > ) {
priority_queue<P, vector<P>, greater<P> > pq;
fill(dist, dist + V, INF);
dist[s] = ;
pq.push(P(, s));
while(!pq.empty()) {
P p = pq.top(); pq.pop();
int v = p.second;
if(dist[v] < p.first) continue;
for(int i = ; i < G[v].size(); i++) {
Edge& e = G[v][i];
if(e.cap > && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
prevv[e.to] = v;
preve[e.to] = i;
pq.push(P(dist[e.to], e.to));
}
}
}
if(dist[t] == INF) return -; for(int v = ; v < V; v++) h[v] += dist[v]; int d = f;
for(int v = t; v != s; v = prevv[v]) {
d = min(d, G[prevv[v]][preve[v]].cap);
}
f -= d;
res += d * h[t];
for(int v = t; v != s; v = prevv[v]) {
Edge& e = G[prevv[v]][preve[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
} int main()
{
//freopen("in.txt", "r", stdin);
int T;
scanf("%d", &T); getchar();
while(T--) {
scanf("%d%d", &n, &m);
for(int i = ; i < maxn; i++) G[i].clear(); for(int i = ; i < n; i++) {
for(int j = ; j < m; j++) {
scanf("%d", &relation[i][j]);
}
} int s = n + n * m, t = s + ;
for(int j = ; j < m; j++) {//工厂
for(int k = ; k < n; k++) {//将工厂拆成n个点
add_edge(n + j * n + k, t, , );
for(int i = ; i < n; i++) {
add_edge(i, n + j * n + k, , (k + ) * relation[i][j]);
}
}
}
for(int i = ; i < n; i++) add_edge(s, i, , );
V = t + ;
printf("%.6f\n", (double)min_cost_flow(s, t, n) / n);
}
return ;
}
POJ 3686 *最小费用流-转化成普通指派问题)的更多相关文章
- B - Housewife Wind POJ - 2763 树剖+边权转化成点权
B - Housewife Wind POJ - 2763 因为树剖+线段树只能解决点权问题,所以这种题目给了边权的一般要转化成点权. 知道这个以后这个题目就很简单了. 怎么转化呢,就把这个边权转化为 ...
- S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的
S - Making the Grade POJ - 3666 这个题目要求把一个给定的序列变成递增或者递减序列的最小代价. 这个是一个dp,对于这个dp的定义我觉得不是很好想,如果第一次碰到的话. ...
- POJ 1060 Modular multiplication of polynomials(多项式的加减乘除,除法转化成减法来求)
题意:给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数. 这里多项式的系数只有1或0,因为题目要求:这里多项式的加减法是将系数相加/减 ...
- BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】
A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...
- 多重背包转化成完全背包 E - Charlie's Change
http://poj.org/problem?id=1787 这个题目我一看就觉得是一个多重背包,但是呢,我不知道怎么输出路径,所以无可奈何,我就只能看一下题解了. 看了题解发现居然是把多重背包转化成 ...
- [LeetCode] Integer to Roman 整数转化成罗马数字
Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...
- HTML5将图片转化成字符画
HTML5将图片转化成字符画 字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢?HTML5让这个可能变成了现实,通过canvas,可以很轻松实现这个功能.其实原理很简单:扫描图片相应位置 ...
- xml格式的数据转化成数组
将得到的xml格式的数据转化成数组 <?php //构造xml $url = "http://api.map.baidu.com/telematics/v3/weather?locat ...
- yii2得到的数据对象转化成数组
yii2得到的数据对象转化成数组需要用到asArray().1.Customer::find(['id' => $id])->asArray()->one();2.$model = ...
随机推荐
- spring 的aop操作
- 修改LINUX ROOT密码
Connecting to 10.10.70.22:22... Connection established. To escape to local shell, press 'Ctrl+Alt+]' ...
- 百度Apollo解析——2.log系统
Apollo中的glog 在Apollo中google glog 被广泛使用,glog 是 google 的一个 c++ 开源日志系统,轻巧灵活,入门简单,而且功能也比较完善. 1. 安装 以下是官方 ...
- go语言的基本命令
go run命令: 用于运行命令源码文件 只能接受一个命令源码文件以及若干个库源码文件作为文件参数其内部操作是:先编译源码文件在执行 -v:列出被编译的代码包的名称 -work: 显示编译时创建的临时 ...
- SpringBoot09 自定义servlet、注册自定义的servlet、过滤器、监听器、拦截器、切面、webmvcconfigureradapter过时问题
1 servlet简介 servlet是一种用于开发动态web资源的技术 参考博客:servlet基础知识 httpservlet详解 2 在springboot应用中添加servlet sp ...
- ruby 【rails在win7_64位操作系统安装】
gem update --system --source http://production.s3.rubygems.org 安装截图
- Linux 编译安装内核
一.简介 内核,是一个操作系统的核心.它负责管理系统的进程.内存.设备驱动程序.文件和网络系统,决定着系统的性能和稳定性.Linux作为一个自由软件,在广大爱好者的支持下,内核版本不断更新.新的内核修 ...
- 7.qfilesystemmodel rowcount 为什么为0? 一个简单的model类的例子
任务: 1.新建一个空的mainwindow项目 2.debug下编译得到一个文件夹,应用程序输出这个文件夹中的文件(不显示文件夹中的文件夹) 3.使用QFileSystemModel完成. 本例显示 ...
- Django框架 之 ORM查询操作详解
Django框架 之 ORM查询操作详解 浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Py ...
- Hive安装及配置
第一步:下载hive并解压 tar zxvf hive-0.8.1-bin.tar.gz 重命名: mv hive-0.8.1-bin hive 给权限:chown hadoop:hadoop hiv ...