ACM: 二分图最佳匹配 图论题 poj 3…
来源:互联网 发布:网络安全工程师年薪 编辑:程序博客网 时间:2024/05/22 02:03
The Windy's is a world famous toy factory that owns Mtop-class workshop to make toys. This year the manager receivesN orders for toys. The manager knows that every order willtake different amount of hours in different workshops. Moreprecisely, the i-th order will take Zijhours if the toys are making in the j-th workshop. Moreover,each order's work must be wholly completed in the same workshop.And a workshop can not switch to another order until it hasfinished the
The manager wants to minimize the average of the finishing timeof the N orders. Can you help him?
Input
The first line of input is the number of test case. The firstline of each test case contains two integers, N and M(1 ≤ N,M ≤ 50).
The next N lines each contain M integers, describingthe matrix Zij (1 ≤ Zij ≤100,000) There is a blank line before each test case.
Output
For each test case output the answer on a single line. Theresult should be rounded to six decimal places.
Sample Input
3
3 4
100 100 100 1
99 99 99 1
98 98 98 1
3 4
1 100 100 100
99 1 99 99
98 98 1 98
3 4
1 100 100 100
1 99 99 99
98 1 98 98
Sample Output
2.0000001.0000001.333333题意: 玩具公司现在有M台机器, N个任务, 要你求出完成每个任务的平均时间最少.
解题思路:
1. 一看题目的时候一头雾水, 看别人的题解: 二分图最佳匹配问题. 想起KM算法.
2. 现在将二分图分成X,Y两部分. X部有N个点, Y部有N*M个点
3. 将每台机器拆成N个点,使得Y部有N*M个点,
(1)第J个机器的第P个点代表: 使用J机器进行倒数第P次加工.
(2)假设N个订单执行的时间分别是t1,t2,t3,...,tn. 执行n个订单的执行时间是:
t1*n + t2*(n-1) + t3*(n-2) + ... + tn-1*2 + tn
(3)将每个机器J拆成N个点,第k个点表示倒数第k个订单在此机器上完成.
连边的权值为: graph[i][j]*k
代码:
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 105
#define _clr(x) memset(x,0xff,sizeof(int)*n)
const int INF = (1<<29);
int graph[MAX][MAX];
int mat[MAX][MAX*MAX];
int match1[MAX*MAX], match2[MAX*MAX];
int n, m;
int kuhn_munkras(int m,int n,int mat[][MAX*MAX],int *match1,int *match2)
{
int s[MAX*MAX], t[MAX*MAX], l1[MAX*MAX], l2[MAX*MAX];
int p, q, i, j, k;
int ret = 0;
for(i = 0; i < m; ++i)
{
l1[i] = -INF;
for(j = 0; j < n; ++j)
{
l1[i] = mat[i][j] > l1[i] ? mat[i][j] : l1[i];
}
}
for(i = 0; i < n; ++i) l2[i] = 0;
_clr(match1), _clr(match2);
for(i = 0; i < m; ++i)
{
for(_clr(t),s[p=q=0] = i; p <= q && match1[i] < 0; ++p)
{
for(k = s[p], j = 0; j < n && match1[i] < 0; ++j)
{
if(l1[k]+l2[j] == mat[k][j] && t[j] < 0)
{
s[++q] = match2[j];
t[j] = k;
if(s[q] < 0)
{
for(p = j; p >= 0; j = p)
{
match2[j] = k = t[j];
p = match1[k];
match1[k] = j;
}
}
}
}
}
if(match1[i] < 0)
{
for(i--, p = INF, k = 0; k <= q; ++k)
for(j = 0; j < n; ++j)
if(t[j] < 0 && l1[s[k]] + l2[j] - mat[s[k]][j] < p)
p = l1[s[k]] + l2[j] - mat[s[k]][j];
for(j = 0; j < n; l2[j] += t[j] < 0 ? 0 : p, j++);
for(k = 0; k <= q; l1[s[k++]] -= p);
}
}
for(i = 0; i < m; ++i)
ret += mat[i][match1[i]];
return ret;
}
int main()
{
//freopen("input.txt","r",stdin);
int i, j;
int caseNum;
scanf("%d",&caseNum);
while(caseNum--)
{
scanf("%d %d",&n,&m);
for(i = 0; i < n; ++i)
{
for(j = 0; j < m; ++j)
scanf("%d",&graph[i][j]);
}
for(i = 0; i < n; ++i)
{
for(j = 0; j < m; ++j)
{
for(int k = 0; k < n; ++k)
{
mat[i][j*n+k] = -graph[i][j]*(k+1);
}
}
}
int result = -kuhn_munkras(n,n*m,mat,match1,match2);
printf("%.6lf\n",(double)result/n);
}
return 0;
}
- ACM: 二分图最佳匹配 图论题 poj 3…
- ACM: 二分图最大匹配 图论题 poj 2…
- ACM: 图论题 poj 3…
- ACM: 图论题 poj 2240 (floyd + ST…
- ACM: 图论题 poj 1…
- ACM: 图论题 poj 1…
- ACM: 匈牙利算法二分图 图论题 poj…
- ACM: 匈牙利算法 图论题 poj 3041 …
- ACM: 差分约束 图论题 poj 2983 sp…
- ACM: 有向欧拉图 图论题 poj 1386 …
- ACM: 图论题 poj 1135
- ACM: 图论题 poj 2253 (poj上的dou…
- ACM: 图论题 poj 1161 (把图重建成…
- ACM: 图论题 poj 1789 (一次AC的水…
- ACM: 图论题 poj 1125 (题意读好久…
- ACM: 图论题 poj 1062 (邻接矩阵+d…
- ACM: 最小费用最大流 图论题 poj 2…
- ACM: 简单最小生成树 图论题 poj 1…
- Smooth Rotation of Object in UNITY
- ACM: 动态规划 华东师范OJ 1244 …
- ACM: 动态规划 黑书上的题目
- ACM: 搜索题 poj 1691 一觉醒来居…
- ACM: 动态规划 poj 1014
- ACM: 二分图最佳匹配 图论题 poj 3…
- ACM: 有向欧拉图 图论题 poj 1386 …
- ACM: 二分图最大匹配 图论题 poj 2…
- Largest prime 尤拉托斯展那筛选法
- ACM: 图论题+记忆DP poj 2662 (边…
- 进程与线程区别
- ACM: 最大流问题 图论题 poj 2263
- ACM: 简单动态规划题 poj 2955
- 第一章 答疑摘选