zoukankan      html  css  js  c++  java
  • 工作分配问题 NOJ 1288 裸KM算法



    工作分配问题

    时间限制(普通/Java) : 20000 MS/ 30000 MS          运行内存限制 : 65536 KByte
    总提交 : 55            测试通过 : 33 

    题目描述

    设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为 c iy 。试设计一个算法,为每一个人都分配件不同的工作,并使总费用达到最小。

    设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小。



    输入

    第一行有个正整数n (1n20)。接下来的n行,每行n个数,表示工作费用。

    输出

    计算出最小总费用。

    样例输入

    3
    10 2 3
    2 3 4
    3 4 5

    样例输出

    9

    提示

    undefined

    跟FFF题类似,不过这题求最小值==把权值改成负的就可以了,最后输出-KM()~

    实现代码:

    <span style="font-size:12px;">#include <cstdio>
    #include <cstring>
    #include <stack>
    #include <vector>
    #include <algorithm>
    #include <map>
    #include <string>
    #include <queue>
    #include <cmath>
    #define ll long long
    int const N = 35;
    int const M = 100005;
    int const INF = 0x3f3f3f3f;
    ll const mod = 1000000007;
    using namespace std;
    int T;
    int n;
    int nx,ny;       //??????????
    int g[N][N];    //??????????
    int linker[N],lx[N],ly[N];      //y????????????????x,y??????????
    int slack[N];
    bool visx[N],visy[N];
    bool DFS(int x)
    {
        visx[x] = true;
        for(int y = 0;y < ny;y++)
        {
            if(visy[y]) continue;
            int tmp = lx[x] + ly[y] -g[x][y];
            if(tmp == 0)
            {
                visy[y] = true;
                if(linker[y] == -1 || DFS(linker[y]))
                {
                    linker[y] = x;
                    return true;
                }
            }
            else if(slack[y] > tmp)
                slack[y] = tmp;
        }
        return false;
    }
    
    int KM()
    {
        memset(linker,-1,sizeof(linker));
        memset(ly,0,sizeof(ly));
        for(int i = 0;i < nx;i++)
        {
            lx[i] = -INF;
            for(int j = 0;j < ny;j++)
                if(g[i][j] > lx[i])
                    lx[i] = g[i][j];
        }
        for(int x =0;x < nx;x++)
        {
            for(int i = 0;i < ny ;i++)
                slack[i] = INF;
            while(true)
            {
                memset(visx,false,sizeof(visx));
                memset(visy,false,sizeof(visy));
                if(DFS(x)) break;
                int d = INF;
                for(int i = 0;i < ny;i++)
                    if(!visy[i] && d > slack[i])
                        d = slack[i];
                for(int i = 0 ; i < nx ;i++)
                    if(visx[i])
                        lx[i] -= d;
                for(int i = 0 ; i < ny ;i++)
                {
                    if(visy[i]) ly[i] += d;
                    else slack[i] -= d;
                }
            }
        }
        int res = 0;
        for(int i = 0;i < ny ;i++)
            if(linker[i] != -1)
                res += g[ linker[i] ][i];
        return res;
    }
    
    void ini()
    {
        scanf("%d",&n);
        int i,j;
        for(i = 0;i < n;i++){
            for(j = 0;j < n;j++)
                {
                    scanf("%d",&g[i][j]);
                    g[i][j]=-g[i][j];
                }
        }
        nx = ny =n;
    }
    
    void solve()
    {
    
    }
    
    void out()
    {
        printf("%d
    ",-KM());
    }
    
    int main()
    {
        ini();
        solve();
        out();
    }</span>

    工作分配问题

    时间限制(普通/Java) : 20000 MS/ 30000 MS          运行内存限制 : 65536 KByte
    总提交 : 55            测试通过 : 33 

    题目描述

    设有n件工作分配给n个人。将工作i分配给第j个人所需的费用为 c iy 。试设计一个算法,为每一个人都分配件不同的工作,并使总费用达到最小。

    设计一个算法,对于给定的工作费用,计算最佳工作分配方案,使总费用达到最小。



    输入

    第一行有个正整数n (1n20)。接下来的n行,每行n个数,表示工作费用。

    输出

    计算出最小总费用。

    样例输入

    3
    10 2 3
    2 3 4
    3 4 5

    样例输出

    9

    提示

    undefined

    题目来源

    算法设计与实验题解

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    课堂作业04 2017.10.27
    课程作业 03 动手动脑 2017.10.20
    课程作业 03 2017.10.20
    HDU 3974 Assign the task
    POJ 2155 Matrix
    POJ 2481 Cows
    HDU 3038 How Many Answers Are Wrong
    CS Academy Array Removal
    POJ_1330 Nearest Common Ancestors LCA
    CF Round 427 D. Palindromic characteristics
  • 原文地址:https://www.cnblogs.com/Tobyuyu/p/4965522.html
Copyright © 2011-2022 走看看