• POJ3686 The Windy's


    POJ3686 The Windy's
    Time Limit: 5000MS Memory Limit: 65536K
    Total Submissions: 2536 Accepted: 1084

    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
    
    ****************************************************************************
    题目大意:有m个工厂, n笔订单, 订单i在j厂完成所需时间为c[i][j], 要求一笔订单只能在一个厂完成, 一个厂不能同时做一笔以上订单, 求一个分配方案, 使得每个任务的平均完成时间最小.
    先来吐糟一下:{首先,我看了题目,发现出不来样例啊!怎么回事,我怎么看不懂样例!然后叫ZYC帮我看,原来是我题意理解错误。然后,我开始建图,纠结,异常纠结,我想呢,我怎么判断第i个订单在第j个车间加工时,第j个车间之前已经加工了什么订单呢?怎么也确定不了,于是,傻掉了。再然后,我上网搜了解题报告,报告是一大堆,讲来讲去说这道题目是好题,建图很巧妙。我懂的啊,图论题目,最难的就是建图嘛。可以,网上的报告,我怎么也就不明白呢,不知道在讲什么,我靠,纠结。再然后,陪XNJ出去买杯子,哦,似乎想通了这道题怎么做,好开心啊,开始写。再然后,我发现怎么也找不出错误,而且貌似是初始化有问题,毛蛋,我把所有数组都清零了还是有问题,这我怎么就这么背捏,一个n写成m了!再然后,我飞速改完,交上去,WA了,发现数组可能要开大一点,再交WA了,也许是某个常数写得太小了改大一点,再交还是WA了,我心都毛了,什么狗蛋啊,和标程对了一下,发现还有一个数组开小了,再交AC。这个AC,我满肚子火啊,太纠结了,唉唉唉!!!}//吐糟结束
    说一下思路,的确像网上众人所说,这道题目的建图异常奇妙。首先碰到的就像我一开始的那个问题,确定不了第i个订单在第j个车间加工时,第j个车间之前已经加工了什么订单。然而换一种想法就想的通了。我们这样想:如果第i个订单在第j个车间加工完后,这个车间又加工了k个订单,那这k个订单每个都需要加上Zij的时间,这个绑定很是特别,需要用心体会,上面那个链接讲得不错,不再赘述。
    #include <stdio.h>
    #include <string.h>
    #include <vector>
    #include <algorithm>
    #define N 55
    #define INF 0x3f3f3f3f
    using namespace std;
    
    int n,m,lack;
    int tu[N][N],gra[N][N*N];
    int mat[N*N],visx[N],visy[N*N];
    int lx[N],ly[N*N];
    
    int dfs(int x)
    {
        visx[x]=1;
        for(int y=1;y<=n*m;y++)
        {
            if(visy[y])continue;
            int t=lx[x]+ly[y]-gra[x][y];
            if(t==0)
            {
                visy[y]=1;
                if(!mat[y]||dfs(mat[y]))
                {
                    mat[y]=x;
                    return 1;
                }
            }
            else lack=min(lack,t);
        }
        return 0;
    }
    
    void re(void)
    {
        scanf("%d%d",&n,&m);
        memset(ly,0,sizeof(ly));
        for(int i=1;i<=n;i++)
        {
            lx[i]=-INF;
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&tu[i][j]);
                for(int k=1;k<=n;k++)
                {
                    gra[i][(j-1)*n+k]=-tu[i][j]*k;
                    lx[i]=max(lx[i],-tu[i][j]*k);
                }
    
            }
        }
    }
    
    void run(void)
    {
        memset(mat,0,sizeof(mat));
        for(int x=1;x<=n;x++)
        {
            memset(visx,0,sizeof(visx));
            memset(visy,0,sizeof(visy));
            lack=INF;
            while(!dfs(x))
            {
                for(int i=1;i<=n;i++)
                    if(visx[i])
                        visx[i]=0,lx[i]-=lack;
                for(int i=1;i<=n*m;i++)
                    if(visy[i])
                        visy[i]=0,ly[i]+=lack;
                lack=INF;
            }
        }
        int ans=0;
        for(int i=1;i<=n*m;i++)
            if(mat[i])
                ans-=gra[mat[i]][i];
        printf("%.6lf\n",1.0*ans/n);
    }
    
    int main()
    {
        int ncase;
        scanf("%d",&ncase);
        while(ncase--)
        {
            re();
            run();
        }
        return 0;
    }
    

      

  • 相关阅读:
    vue项目本地调试,内网穿透
    EMQ开启mysql认证
    vsftpd配置安装
    express使用https
    vue实现图片的上传和删除
    Linux下获取java堆栈文件并进行分析
    kill -3 PID命令获取java应用堆栈信息
    Linux下的java虚拟机性能监控与故障处理命令
    k8s下的eureak服务注册失败(cannot execute request on any known server)解决
    MariaDB主从复制虚拟机实战
  • 原文地址:https://www.cnblogs.com/Fatedayt/p/2216905.html
Copyright © 2020-2023  润新知