• poj3686 The Windy's


    The Windy's
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 5733   Accepted: 2369

    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
    
    

    Source

    题目大意:n个玩具在m个工厂内加工,给出每个玩具在不同工厂加工所用的时间,一个工厂在任意时刻内最多只能加工一个玩具,求所有玩具的最小平均等待时间.
    分析:复杂的匹配问题(指派问题).要求最小化所有玩具的平均等待时间其实只需要最小化所有玩具的等待时间.
              只考虑一个工厂,如果该工厂加工3个玩具,那么总等待时间就是a1 * 3 + a2 * 2 + a3*3,每个玩具的加工时间前都会有一个系数.那么可以考虑将工厂拆点(加工了k-1个玩具,当前加工第k个玩具),那么对应的玩具加工时间*k就是对答案的贡献了,最后求一下最小费用最大流就可以了.
              坑点:1.编号问题需要注意. 2.会有多达n*m+n+1个点,连边的数量会上30w,数组要适当开大.  3.多次清空vis数组会T掉,用时间戳优化.
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 100010,inf = 0x3f3f3f3f;
    int head[maxn],to[maxn],nextt[maxn],w[maxn],c[maxn],tot = 2;
    int t,n,m,S,T,ans,d[maxn],vis[maxn],vis2[maxn];
    int dfs_clock,dfs_clock2;
    
    void init()
    {
        memset(head,0,sizeof(head));
        tot = 2;
        ans = 0;
        dfs_clock = dfs_clock2 = 0;
    }
    
    void add(int x,int y,int z,int p)
    {
        c[tot] = p;
        w[tot] = z;
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;
    
        c[tot] = -p;
        w[tot] = 0;
        to[tot] = x;
        nextt[tot] = head[y];
        head[y] = tot++;
    }
    
    bool spfa()
    {
        queue <int> q;
        memset(d,inf,sizeof(d));
        dfs_clock++;
        dfs_clock2++;
        d[S] = 0;
        vis[S] = dfs_clock;
        q.push(S);
        while (!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u];i;i = nextt[i])
            {
                int v = to[i];
                if (w[i] && d[v] > d[u] + c[i])
                {
                    d[v] = d[u] + c[i];
                    if (vis[v] != dfs_clock)
                    {
                        vis[v] = dfs_clock;
                        q.push(v);
                    }
                }
            }
        }
        return d[T] < inf;
    }
    
    int dfs(int u,int f)
    {
        if (u == T)
        {
            ans += f * d[T];
            return f;
        }
        int res = 0;
        vis2[u] = dfs_clock2;
        for (int i = head[u];i;i = nextt[i])
        {
            int v = to[i];
            if (vis2[v] != dfs_clock2 && w[i] && d[v] == d[u] + c[i])
            {
                int temp = dfs(v,min(f - res,w[i]));
                res += temp;
                w[i] -= temp;
                w[i ^ 1] += temp;
                if (res == f)
                    return res;
            }
        }
        return res;
    }
    
    void dinic()
    {
        while (spfa())
            dfs(S,inf);
    }
    
    int main()
    {
        scanf("%d",&t);
        while (t--)
        {
            init();
            scanf("%d%d",&n,&m);
            S = 0,T = m * n + n + 1;
            for (int i = 1; i <= n; i++)
                add(S,i,1,0);
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= m; j++)
                {
                    int tt;
                    scanf("%d",&tt);
                    for (int k = 1; k <= n; k++)
                        add(i,j * n + k,inf,tt * k);
                }
            for (int i = 1; i <= m; i++)
                for (int j = 1; j <= n; j++)
                    add(i * n + j,T,1,0);
            dinic();
            double anss = (double)ans / n;
            printf("%.6lf
    ",anss);
        }
    
        return 0;
    }
  • 相关阅读:
    Python量化分析,计算KDJ
    Ubuntu16.04安装Python3.6 和pip(python3 各版本切换)
    使用docker加载已有镜像安装Hyperledger Fabric v1.1.0
    Ubuntu 16.04将左侧面板置于底部
    解决Flask局域网内访问不了的问题
    Ubuntu 16.04 安装Go 1.9.2
    Ubuntu16.04下安装Hyperledger Fabric 1.0.0
    Ubuntu 16.04安装Docker-CE
    用Python抓取网页并解析
    图解python中赋值、浅拷贝、深拷贝的区别
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8149441.html
Copyright © 2020-2023  润新知