题意:n个订单和m个生产车间,每个订单在不同的车间生产所需要的时间不一样,并且每个订单只能在同一个车间中完成,直到这个车间完成这个订单就可以生产下一个订单.现在需要求完成n个订单的平均时间最少是多少.(每个订单的单独时间之和/n,包括等待时间)。

主要是建图,考虑第i个订单在第j个车间倒数第k个被生产,那么第i个订单在第j个区间所花费的时间为k*mat[i][j].

每个区间最多生产n个订单,那么就可以把n*m的图转化成n*(n*m)的图进而用km算法求最小权值。

所以把每个权值取反进而求最大权匹配,但是为什么不能直接求最小权匹配还是没想清楚.

注意G++用%f输出,否则wa.

参考:http://www.tuicool.com/articles/jmYNryf

 #include<iostream>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int nMax = ;
const int mMax = ;
const int inf = ; int n, m; // n为X集合顶点数量,m为Y集合顶点数量。(1~n和1~m)
int map[nMax][mMax]; // map[i][j]:记录X集合中的i到Y集合中的j所需的费用。
int lx[nMax], ly[mMax];
int link[mMax];
bool x[nMax], y[mMax]; bool dfs(int u){ // 判断能否找到最大完全匹配。
x[u] = true;
for(int v = ; v <= m; v ++)
if(!y[v] && lx[u] + ly[v] == map[u][v]){
y[v] = true;
if(!link[v] || dfs(link[v])){
link[v] = u;
return true;
}
}
return false;
} int KM(){ // KM算法。
int i, j, k, mi;
for(i = ; i <= n; i ++)
for(lx[i] = -inf, j = ; j <= m; j ++)
lx[i] = max(lx[i], map[i][j]);
memset(ly, , sizeof(ly));
memset(link, , sizeof(link));
for(k = ; k <= n; k ++){
while(){
memset(x, , sizeof(x));
memset(y, , sizeof(y));
if(dfs(k)) break;
mi = inf;
for(i = ; i <= n; i ++)
if(x[i])
for(j = ; j <= m; j ++)
if(!y[j])
mi = min(mi, lx[i] + ly[j] - map[i][j]);
for(i = ; i <= n; i ++) if(x[i]) lx[i] -= mi;
for(i = ; i <= m; i ++) if(y[i]) ly[i] += mi;
}
}
int ans = ;
for(i = ; i <= m; i ++)
if(link[i] > )
ans += map[link[i]][i];
return ans;
} int main(){
int t, N, M, i, j, k, mat[nMax][nMax];
scanf("%d", &t);
while(t --){
scanf("%d%d", &N, &M);
for(i = ; i <= N; i ++)
for(j = ; j <= M; j ++)
scanf("%d", &mat[i][j]);
n = N, m = N * M;
for(i = ; i <= N; i ++) // KM算法是求最大权,故这里存负数,最后取反求最小权。
for(j = ; j <= N; j ++)
for(k = ; k <= M; k ++){
map[i][(k-)*N+j] = -j*mat[i][k];
//cout << i << ' ' << (k-1)*N+j << ' ' << j*mat[i][k] << endl;
}
double ans = 1.0*(-KM())/N; // 精度必须取double才AC。
printf("%.6f\n", ans);
}
return ;
}

这题还可以用费用流来解决.不过效率没有KM高.

初始源点和每个订单相连,每个车间拆成n*m个车间,然后和汇点相连.然后和km考虑的一样在订单和车间之间连边.

 #include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
const int INF = 1e9;
struct edge{
int to,next;
int cap,flow,cost;
}e[maxn*maxn];
int n,m;
int head[maxn],sz,res;
bool inq[maxn];
int p[maxn],d[maxn],a[maxn];
void addedge(int u,int v,int cap,int cost){
e[sz].to = v;e[sz].next = head[u];
e[sz].cap = cap;e[sz].flow = ;e[sz].cost = cost;
head[u] = sz ++;
e[sz].to = u;e[sz].next = head[v];
e[sz].cap = ;e[sz].flow = ;e[sz].cost = -cost;
head[v] = sz ++;
}
void init(){
memset(head,-,sizeof(head));
sz = ;
}
queue<int> Q;
int SPFA(int s,int t){
memset(inq,,sizeof(inq));
for(int i = ; i <= t ; i ++) d[i] = INF;
inq[s] = ;d[s] = ;p[s] = -;
a[s] = INF;
Q.push(s);
while(!Q.empty()){
int u = Q.front();Q.pop();
inq[u] = ;
for(int i = head[u] ; i != - ; i = e[i].next){
int v = e[i].to;
if(e[i].cap - e[i].flow > && e[i].cost + d[u] < d[v]){
d[v] = d[u] + e[i].cost;
a[v] = min(e[i].cap - e[i].flow,a[u]);
p[v] = i;
if(!inq[v]){
inq[v] = ;
Q.push(v);
}
}
}
}
int u = t;
if(d[t] == INF) return ;
res += d[t] * a[t];
while(u != s){
e[ p[u] ].flow += a[t];
e[ p[u] ^ ].flow -= a[t];
u = e[ p[u] ^ ].to;
}
return ;
} void MCMF(int s,int t){
res = ;
while(SPFA(s,t));
printf("%.6f\n",res*1.0/n);
} void solve(){
init();
int s,t,mat[][];
scanf("%d%d",&n,&m);
s = ;t = n * m + n + ;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
scanf("%d",&mat[i][j]);
for(int i = ; i <= n; i ++)
{
addedge(s,i,,);
for(int j = ; j <= n; j ++)
{
for(int k = ; k <= m; k ++)
{
addedge(i,n+(k-)*n+j,,j*mat[i][k]);
}
}
}
for(int i=n+;i<=n*m+n;i++)
addedge(i,t,,);
MCMF(s,t);
}
int main()
{
//freopen("a.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--) solve();
return ;
}

poj - 3686 The Windy's (KM算法)的更多相关文章

  1. [ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

    The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Descr ...

  2. POJ 3686 The Windy's(思维+费用流好题)

    The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5362   Accepted: 2249 Descr ...

  3. poj 3565 uva 1411 Ants KM算法求最小权

    由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...

  4. poj 3686 The Windy's

    http://poj.org/problem?id=3686 #include <cstdio> #include <cstring> #include <algorit ...

  5. POJ 2195 Going Home(KM算法模板)

    题目链接:http://poj.org/problem?id=2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致. man每移动一格需花费$1 ...

  6. POJ 3686 The Windy's (费用流)

    [题目链接] http://poj.org/problem?id=3686 [题目大意] 每个工厂对于每种玩具的加工时间都是不同的, 并且在加工完一种玩具之后才能加工另一种,现在求加工完每种玩具的平均 ...

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

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

  8. POJ 3686 The Windy's 最小费用最大流

    每个工厂拆成N个工厂,费用分别为1~N倍原费用. //#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...

  9. POJ 3686 The Windy's (最小费用流或最佳完全匹配)

    题意:有n个订单m个车间,每个车间均可以单独完成任何一个订单.每个车间完成不同订单的时间是不同的.不会出现两个车间完成同一个订单的情况.给出每个订单在某个车间完成所用的时间.问订单完成的平均时间是多少 ...

随机推荐

  1. mysql 查询数据库参数命令

    1.select @@tx_isolation;    查询数据库设置的事务隔离级别 2.desc table_name;  显示表设计 3.show create table table_name; ...

  2. 031_spark架构原理

    spark核心组件 driver master worker executor task(只有task是线程) 核心组件的原理图解

  3. mysql出错排查

    1,例如:Can't connect to local MySQL server through socket '/tmp/mysql-5.5.37.sock' (2) Mysql链接出错,请配置/A ...

  4. syntax error : missing ';' before identifier

    原文解决方案 #include "string.h" #include "stdafx.h" #include "Chapter 01 MyVersi ...

  5. Qt _六天的学习路线

    六天的学习路线:第一天:    1.Qt的介绍    2.Qt的框架    3.项目文件(.pro)    4.第一个Qt程序(hello Qt)    5.父窗口和子窗口的区别(控件,部件,构件)  ...

  6. python数组中数据位置交换 -- IndexError: list assignment index out of range

    代码: t = [-10,-3,-100,-1000,-239,1] # 交换 -10和1的位置 t[5], t[t[5]-1] = t[t[5]-1], t[5] 报错: IndexError: l ...

  7. 洛谷 P3146 248 题解

    https://www.luogu.org/problemnew/show/P3146 区间dp,这次设计的状态和一般的有一定的差异. 这次我们定义$dp[i][j]$表示$[i,j]$的可以合并出来 ...

  8. luogu P1407 稳定婚姻-tarjan

    题目背景 原<工资>重题请做2397 题目描述 我国的离婚率连续7年上升,今年的头两季,平均每天有近5000对夫妇离婚,大城市的离婚率上升最快,有研究婚姻问题的专家认为,是与简化离婚手续有 ...

  9. 计算机网络之TCP拥塞控制

    1. 首先,拥塞控制和流量控制是不一样的. 拥塞控制是防止过多的数据注入到网络中,可以使网络中的路由器或链路不致过载,是一个全局性的过程.  流量控制是点对点通信量的控制,是一个端到端的问题,主要就是 ...

  10. js实现复制粘贴功能

    在项目中使用到复制粘贴功能,虽然网上有很多大牛封装了很多的插件,但是还是想不去使用插件,就像自己来实现这个功能. 另一篇是禁止复制粘贴 前端er怎样操作剪切复制以及禁止复制+破解等 初步想法: 1. ...