• 【二分图匹配入门专题1】poj3686 【km+思维建图】


                                    The Windy's
     

    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个机器,输入n*m的矩阵,矩阵值为每个机器处理一笔订单所花时间,每个机器只能处理完一笔订单后才能处理下一笔订单,问,最小的平均花费时间为多少。
    思路:每个机器最多可以处理n个订单,假设处理每个订单花费时间为a1,a2,a3..an
       那么一个机器处理n个订单花费的时间为a1+(a1+a2)+(a1+a2+a3)...= a1*n+a2*(n-1)+...an
       第i订单倒数第k个处理时,耗费时间为ai*k.
       我们把j机器倒数处理i订单的情况分为k个点,那么对于每一个订单i,在每个机器j上所花费的时间就是map[i][1..m*n]=cost*k
       建图比较难想到,自己也是看了别人的题解才知道
    ~~~~今天成功被这两道题的bug给恶心的没谁了,这道题自己在判断增广路的if语句后加了一个分号;找bug的时间基本可以和写这道题的时间相当(泪目~),上一道题自己
      把double变量定义为int型,还疑惑为什么精度不够,哎哎哎,自己这个样子以后还怎么愉快的刷题啊~~~
       


     

    #include<stdio.h>
    #include<string.h>
    #define N 55
    #define INF 0x3f3f3f3f
    int map[N][N*N],visx[N],visy[N*N];
    int linker[N*N],lx[N],ly[N*N];
    int cost;
    int n,m,nx,ny,d;
    
    int dfs(int x)
    {
        int y,tmp;
        visx[x] = 1;
        for(y = 1; y <= ny; y ++)
        {
            if(!visy[y])
            {
                tmp = lx[x] + ly[y] - map[x][y];
                if(!tmp)
                {
                    visy[y] = 1;
                    if(linker[y]==-1||dfs(linker[y]))
                    {
                        linker[y] = x;
                        return 1;
                    }
                }
                else if(d > tmp)
                    d = tmp;
            }
        }
        return 0;
    }
    
    int KM()
    {
        int sum,x,i,j;
        memset(linker,-1,sizeof(linker));
        memset(ly,0,sizeof(ly));
        for(i = 1; i <= nx; i ++)
            for(j = 1,lx[i]=-INF; j <= ny; j ++)
                if(lx[i] < map[i][j])
                {
                    lx[i] = map[i][j];
                }        
        for(x= 1; x <= nx ; x ++)
        {
            while(1)
            {
                memset(visx,0,sizeof(visx));
                memset(visy,0,sizeof(visy));
                d = INF;
                if(dfs(x))//;就是这个bug!!!!
                    break;
                for(i = 1; i <= nx; i ++)
                    if(visx[i])
                        lx[i] -= d;
                for(i = 1; i <= ny; i ++)
                    if(visy[i])
                        ly[i] += d;    
            }
        }
        sum = 0;
        for(i = 1; i <= ny; i ++)
            if(linker[i]!=-1)
                sum += map[linker[i]][i];
        return -sum;    
    }
    
    int main()
    {
        int t,sum;
        double ans;
        scanf("%d",&t);
        while(t -- )
        {
            scanf("%d%d",&n,&m);
            for(int i = 1; i <= n; i ++)
            {
                sum = 0;
                for(int j = 1; j <= m;j ++)
                {
                    scanf("%d",&cost);
                    for(int k = 1; k <= n; k ++)
                        map[i][++sum] = - k*cost;
                }
            }    
            nx = n;
            ny = n*m;
            ans = KM()*1.0/n;
            printf("%.6lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    无限极分类,递归分类
    foreach加循环体与不加循环体的区别
    图片base64上传时可能遇到的问题
    php(curl请求)测试接口案例
    PHP取得json前面有乱码(去除文件头部BOM)
    PHP计算连续签到天数以及累计签到天数
    原生端与服务器通过sessionid实现session共享以及登录验证
    php安装xunserch
    ROS学习(二)运行keyboard
    ROS学习(一)Ros 中使用kinect
  • 原文地址:https://www.cnblogs.com/hellocheng/p/7365966.html
Copyright © 2020-2023  润新知