题意】

有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 *最小费用流-转化成普通指派问题)的更多相关文章

  1. B - Housewife Wind POJ - 2763 树剖+边权转化成点权

    B - Housewife Wind POJ - 2763 因为树剖+线段树只能解决点权问题,所以这种题目给了边权的一般要转化成点权. 知道这个以后这个题目就很简单了. 怎么转化呢,就把这个边权转化为 ...

  2. S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的

    S - Making the Grade POJ - 3666 这个题目要求把一个给定的序列变成递增或者递减序列的最小代价. 这个是一个dp,对于这个dp的定义我觉得不是很好想,如果第一次碰到的话. ...

  3. POJ 1060 Modular multiplication of polynomials(多项式的加减乘除,除法转化成减法来求)

    题意:给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数. 这里多项式的系数只有1或0,因为题目要求:这里多项式的加减法是将系数相加/减 ...

  4. BNU 28887——A Simple Tree Problem——————【将多子树转化成线段树+区间更新】

    A Simple Tree Problem Time Limit: 3000ms Memory Limit: 65536KB This problem will be judged on ZJU. O ...

  5. 多重背包转化成完全背包 E - Charlie's Change

    http://poj.org/problem?id=1787 这个题目我一看就觉得是一个多重背包,但是呢,我不知道怎么输出路径,所以无可奈何,我就只能看一下题解了. 看了题解发现居然是把多重背包转化成 ...

  6. [LeetCode] Integer to Roman 整数转化成罗马数字

    Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 t ...

  7. HTML5将图片转化成字符画

    HTML5将图片转化成字符画 字符画大家一定非常熟悉了,那么如何把一张现有的图片转成字符画呢?HTML5让这个可能变成了现实,通过canvas,可以很轻松实现这个功能.其实原理很简单:扫描图片相应位置 ...

  8. xml格式的数据转化成数组

    将得到的xml格式的数据转化成数组 <?php //构造xml $url = "http://api.map.baidu.com/telematics/v3/weather?locat ...

  9. yii2得到的数据对象转化成数组

    yii2得到的数据对象转化成数组需要用到asArray().1.Customer::find(['id' => $id])->asArray()->one();2.$model = ...

随机推荐

  1. 嵌入式Linux启动优化手记2&nbsp;U…

    参考一下 原文地址:U-boot优化">嵌入式Linux启动优化手记2 U-boot优化作者:ZhaoJunling 既然不能使用新的U-boot,那就优化一点是一点,慢慢干吧. 1. ...

  2. Ubuntu14.04 安装Source Insight

    在Ubuntu中,安装Windows程序用wine,然后用wine安装Windows软件即可. 1.安装wine 在终端输入以下命令: sudo apt-get install wine 2.用win ...

  3. Tornado之抽屉实战(1)--分析与架构

    项目模拟地址:http://dig.chouti.com/ 知识点应用: AJAX  用于偷偷发请求 原生ajax jQuery  ajax($.ajax) iframe伪造 上传文件 传统Form ...

  4. cocos2dx中坐标系

    CCNode类的setPosition,getPosition函数如果是一个Node的Child则获取的坐标就是该Node的本地坐标 另一个关键问题就是在cocos2d-x里就是各种对象的大小问题.因 ...

  5. Spring第五天

    1. [简答题]:简述一下hibernate和spring框架的整合步骤: 答: 1.加入hibernate jar包 2.编写持久化类 3.添加Hibernate的配置文件:hibernate.cf ...

  6. php学习笔记-定义数组和引用数组元素

    上图包含两种定义数组的方法,一种是通过数组索引来创建的,一种是通过array()函数来创建的.

  7. for与break的用法

    # Auther: Aaron Fan age_of_oldboy = 56 #执行3次循环for i in range(3): guess_age = int(input("猜一下oldb ...

  8. Google B4网络阅读记录(翻译)

    3.设计 这一章我们描述软件定义广域网架构的细节. 3.1.概述 我们的软件定义网络从逻辑上可以看做三层,如图所示, B4服务于多个广域网节点,每个节点都有很多服务器集群.在每个B4节点内,交换机硬件 ...

  9. Understanding the Effective Receptive Field in Deep Convolutional Neural Networks

    Understanding the Effective Receptive Field in Deep Convolutional Neural Networks 理解深度卷积神经网络中的有效感受野 ...

  10. Redhat 6 git服务器配置 (git-daemon)

    git-daemon是按照git的自己的git协议进行访问git服务   1.git-daemon软件安装 软件仓库见 redhat 6 git 服务器 配置 (http)   2.配置git dae ...