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 = ...
随机推荐
- 字符串解压缩类库(zip、GZIP、QuickLz、snappy、lzf、jzlib)介绍
1.ZIP. GZIP 计算机文件压缩算法,JDK中java.util.zip.*中实现.主要包括ZipInputStream/ ZipOutputStream.GZipInputStream/Zi ...
- 玩转Jquery
一 jquery简介 1 jquery是什么 jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. jQuery是继prototype ...
- 定时node-schedule 模块的使用
You can install using npm. npm install node-schedule var schedule = require('node-schedule'); var j ...
- Node内存限制与垃圾回收
对象分配 所有的JS对象都是通过堆来进行分配的.使用process.memoryUsage()查看使用情况Node.js 中文网文档 process.memoryUsage() { rss: , he ...
- Spring_01 spring容器、控制反转(IOC)、依赖注入(DI)
目录 1 什么是spring框架 2 spring框架的特点 3 spring容器 3.1 什么是spring容器 3.2 spring容器创建对象的编程步骤 3.4 spring容器创建对象的方式 ...
- JDBC MySQL 实例之 用户管理系统
1 Java 和 MySQL 怎么建立连接 2 通过Java怎么对数据库进行操作 package day01; import java.sql.Connection; import java.sql. ...
- 项目一:第八天 1、前台系统导入 实现客户注册 发验证码,邮件 springdata-redis存储数据 3、实现客户登陆
1 前台系统客户注册功能 页面:signup.html 1.1 验证手机号是否注册(邮箱同样) 1. 使用Jquery-validate插件进行相关校验,使用校验规则 <input type=& ...
- can基础知识介绍
1.什么是can 2.can的特点 2.物理层特征 我们使用ISO11898标准,物理层特征如图所示 3.帧的种类介绍 实际上有一些帧是有硬件来实现的. 4.数据帧介绍 5.总线仲裁 6.位时序(用于 ...
- python---pyspider,报错?
conf.json文件内容如下: { "message_queue": "redis://127.0.0.1:6379/15", "webui&quo ...
- 《Effective Java》第3章 对于所有对象都通用的方法
第8条:覆盖equals时请遵守通用约定 覆盖equals方法看起来似乎很简单,但是有许多覆盖方式会导致错误,并且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每 ...