poj - 3686 The Windy's (KM算法)
题意: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算法)的更多相关文章
- [ACM] POJ 3686 The Windy's (二分图最小权匹配,KM算法,特殊建图)
The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 4158 Accepted: 1777 Descr ...
- POJ 3686 The Windy's(思维+费用流好题)
The Windy's Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 5362 Accepted: 2249 Descr ...
- poj 3565 uva 1411 Ants KM算法求最小权
由于涉及到实数,一定,一定不能直接等于,一定,一定加一个误差<0.00001,坑死了…… 有两种事物,不难想到用二分图.这里涉及到一个有趣的问题,这个二分图的完美匹配的最小权值和就是答案.为啥呢 ...
- poj 3686 The Windy's
http://poj.org/problem?id=3686 #include <cstdio> #include <cstring> #include <algorit ...
- POJ 2195 Going Home(KM算法模板)
题目链接:http://poj.org/problem?id=2195 题目大意: 给定一个N*M的地图,地图上有若干个man和house,且man与house的数量一致. man每移动一格需花费$1 ...
- POJ 3686 The Windy's (费用流)
[题目链接] http://poj.org/problem?id=3686 [题目大意] 每个工厂对于每种玩具的加工时间都是不同的, 并且在加工完一种玩具之后才能加工另一种,现在求加工完每种玩具的平均 ...
- POJ-3686 The Windy's KM算法 拆点题
参考:https://blog.csdn.net/sr_19930829/article/details/40680053 题意: 有n个订单,m个工厂,第i个订单在第j个工厂生产的时间为t[i][j ...
- POJ 3686 The Windy's 最小费用最大流
每个工厂拆成N个工厂,费用分别为1~N倍原费用. //#pragma comment(linker, "/STACK:1024000000,1024000000") #includ ...
- POJ 3686 The Windy's (最小费用流或最佳完全匹配)
题意:有n个订单m个车间,每个车间均可以单独完成任何一个订单.每个车间完成不同订单的时间是不同的.不会出现两个车间完成同一个订单的情况.给出每个订单在某个车间完成所用的时间.问订单完成的平均时间是多少 ...
随机推荐
- B/S网络架构
B/S基于统一的应用层协议HTTP来交互数据,目前的B/S网络架构大多采用如图所示的架构设计,既要满足海量用户访问请求,又要保持用户请求的快速响应. 当一个用户在浏览器输入www.taobao.com ...
- Hello Shell
shell是Linux平台的瑞士军刀,能够自动化完成很多工作.要了解UNIX 系统中可用的 Shell,可以使用 cat /etc/shells 命令.使用 chsh 命令 更改为所列出的任何 She ...
- 利用Jenkins打包ISO和QCOW2镜像文件
现在的云虚拟化环境越来越多,经常会碰到需要修改并重新打包新的ISO或QCOW2镜像文件.通过手工的方式会比较麻烦,所以在镜像发布的生产环境中可以利用Jenkins来进行定期打包发布,以下介绍Jenki ...
- ECharts是我接触过的最优秀的可视化工具,也是进步最快的软件,希望它早日成为世界级的开源项目。
ECharts的广泛网址: http://echarts.baidu.com/doc/example.html 零编程玩转图表: http://tushuo.baidu.com/?qq-pf-to=p ...
- dns config
.: { forward . { force_tcp expire 50s health_check 50s } cache debug errors whoami log } Corefile .: ...
- 全局/局部变量、宏、const、static、extern
#pragma mark--全局变量和局部变量 根据变量的作用域,变量可以分为: 一.全局变量 1> 定义:在函数外面定义的变量2> 作用域:从定义变量的那一行开始,一直到文件结尾(能被后 ...
- Node.js快速生成26个字母
const buf1 = Buffer.allocUnsafe(26); for (let i = 0; i < 26; i++) { // 97 是 'a' 的十进制 ASCII 值. buf ...
- 如何用纯 CSS 创作一个同心圆弧旋转 loader 特效
效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/OZmXQX 可交互视频教程 此视 ...
- HTML5编辑API之Range对象
Range对象代表页面上的一段连续区域,通过Range对象,可以获取或修改页面上的任何区域,可以通过如下创建一个空的Range对象,如下: var range = document.createRa ...
- 【BZOJ 1084】 [SCOI2005]最大子矩阵(DP)
题链 http://www.lydsy.com/JudgeOnline/problem.php?id=1084 Description 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩 ...