The Windy's - POJ 3686 KM算法

原创 2015年07月07日 20:31:30

The Windy's
Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 4408   Accepted: 1874

Description

The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The manager knows that every order will take different amount of hours in different workshops. More precisely, the i-th order will take Zij hours 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 has finished the previous one. The switch does not cost any time.

The manager wants to minimize the average of the finishing time of the N orders. Can you help him?

Input

The first line of input is the number of test case. The first line of each test case contains two integers, N and M (1 ≤ N,M ≤ 50).
The next N lines each contain M integers, describing the 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. The result 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.000000
1.000000
1.333333

题意:有n个物品,m个制造车间,每个物品在一个车间内制造有相应的时间,问所有商品从开始到制作完成的时间的和的平均值最小是多少。

思路:用KM算法,一边是n个物品,一边是n*m的矩阵,表示a个物品在第j个车间里是第倒数i个完成的。对应的权值是cost[a][j]*i,可以这么理解:它在倒数第i个完成后,对后面的i-1个物品等待其花费的时间加入这个权值当中。

AC代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int T,t,n,m,w[60][2600],cost[60][60],nx,ny,INF=1e9;
int lx[60],ly[2600],linky[2600],slack[2600];
bool visx[60],visy[2600];
bool Find(int x)
{
    int y,t;
    visx[x]=1;
    for(y=1;y<=ny;y++)
       if(!visy[y])
       {
           t=lx[x]+ly[y]-w[x][y];
           if(t==0)
           {
               visy[y]=1;
               if(linky[y]==-1 || Find(linky[y]))
               {
                   linky[y]=x;
                   return 1;
               }
           }
           else if(slack[y]>t)
             slack[y]=t;
       }
    return false;
}
int KM()
{
    int i,j,k,x,y,d,ans=0;
    memset(linky,-1,sizeof(linky));
    memset(ly,0,sizeof(ly));
    for(i=1;i<=nx;i++)
    {
        lx[i]=-INF;
        for(j=1;j<=ny;j++)
           lx[i]=max(lx[i],w[i][j]);
    }
    for(i=1;i<=nx;i++)
    {
        for(j=1;j<=ny;j++)
           slack[j]=INF;
        while(true)
        {
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            if(Find(i))
              break;
            d=INF;
            for(j=1;j<=ny;j++)
               if(!visy[j] && d>slack[j])
                 d=slack[j];
            for(j=1;j<=nx;j++)
               if(visx[j])
                 lx[j]-=d;
            for(j=1;j<=ny;j++)
               if(visy[j])
                  ly[j]+=d;
               else
                 slack[j]-=d;
        }
    }
    for(j=1;j<=ny;j++)
       if(linky[j]>-1)
         ans+=w[linky[j]][j];
    return ans;
}
int main()
{
    int i,j,k,ans;
    scanf("%d",&T);
    for(t=1;t<=T;t++)
    {
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++)
           for(j=1;j<=m;j++)
              scanf("%d",&cost[i][j]);

        nx=n;ny=n*m;
        for(i=1;i<=n;i++)
           for(j=1;j<=n;j++)
              for(k=1;k<=m;k++)
                 w[i][(j-1)*m+k]=-cost[i][k]*j;
        ans=KM();
        printf("%.6f\n",-1.0*ans/n);
     }
}



相关文章推荐

poj 3686 The Windy's 二分匹配 KM算法求最小权匹配

题意:有M个工作间,N个玩具订单,求最小的平均完成时间              思路:对M个工作间分成N个点,j的第p个点表示倒数第p次加工,若要在一个工作间上完成k个订单则需要假设我们按顺序在J...

poj3686 The Windy's KM算法

题意: 有n个订单,m个机器。每个机器同时只能处理一个订单,问最小的平均时间是多少。 平均时间=总时间/订单数。 总时间是等待的时间加上处理的时间。 思路: 对于一个机器,假如有k个...

POJ 3686 The Windy's KM算法

这题的建图实在是太神了 假设某个机器处理了k个玩具,那么对于这些玩具,有两种时间,一种是真正处理的时间,一种是等待的时间,等待的时间就是之前所有处理的玩具的时间, 假设这k个玩具真正用在加...

【POJ 3686】【最小费用最大流或者KM算法 指派问题变形(需要拆点)】The Windy's n个玩具指派给m个工厂生产

传送门:POJ 3686 The Windy's 描述: The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Sub...

Poj 3686 The Windy's【KM匹配】

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5048   Ac...

POJ-3686-The Windy's(KM/费用流)

链接:http://poj.org/problem?id=3686 N个订单M个车间,N*M的矩阵给出第i个订单在第j个车间生产所需时间,车间有任务则需等待,求完成所有订单所需的平均时间; 对于同一个...

POJ_3686_The Windy's(最小费用流 / KM)

题意:现在要加工M个产品,然后N个工厂,告诉产品在每个工厂加工所需的时间,一个工厂每次只能加工一个产品,现在问加工所有产品所用的时间平均数最小是多少。 分析:假设有k个产品在a工厂加工,那么总时间就...

POJ 3686 The Windy's KM模版+拆点建图

题目的意思是:有N个订单和M个机器,给出第i个订单在第j个机器完成的时间Mij,每台机器同一时刻只能处理一个订单,机器必须完整地完成一个订单后才能接着完成下一个订单。问N个订单完成时间的平均值最少为多...

poj 3686 The Windy's 二分图最小权和匹配KM

KM算法解二分图最小权和匹配的经典构图例题
  • sepNINE
  • sepNINE
  • 2014年12月06日 11:08
  • 648

POJ--3686[The Windy's] 最小费用流或KM

题意: 有N个任务和M个机器,给出第i个任务在第j个机器完成的时间map[i][j],每台机器同一时刻只能处理一个任务,机器必须完整地完成一个任务后才能接着完成下一个任务。问N个任务完成时间的平均值...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:The Windy's - POJ 3686 KM算法
举报原因:
原因补充:

(最多只允许输入30个字)