Sicily 1303. Job Assignment

1303. Job Assignment

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

One problem comes up when we are trying to assign jobs about GDCPC’2003 (ZSUCPC’2003) to staffs. Because some of them complain that the tasks assigned to them are so bother. This emotion will lead to very bad effect in sequence. So we try to satisfy every staff as possible as we can. At first, we make an investigation to get the information about staffs’ attitude towards every task. And then we evaluate each attitude as a point (a positive integer number not larger than 100). The higher the point is, the more the staff is satisfied. Because the staffs are very busy, they have only a little leisure time to finish the task. So we just assign one task to one person, of course, one task can not be assigned to different persons. Now we give you all the points and hope you can help us to assign the tasks to make the sum of the points which correspond the assignment is maximum.

Input

Input will contain several test cases. The first line of each test case only contains one integer number N (0≤N≤100). N is the number of staffs, also is the number of tasks. And then, the following N lines describe staffs’ attitude. Each line contains n positive integer numbers. The jth number in the ith line describes ith staff‘s attitude to the jth task.

N=0 indicates the end of input file.

Output

For each test case you should output one line, and just one number in this line. The number is the maximum.

Sample Input

210 9080 100350 60 7070 75 8080 90 1000

Sample Output

170230

Problem Source

ZSUACM Team Member

// Problem#: 1303
// Submission#: 3462789
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <iomanip>
#include <algorithm>
#include <queue>
#include <functional>
#include <map>
#include <string.h>
#include <math.h>
#include <list>
#include <set>
using namespace std;

const int MAXN = 105;

int v[MAXN][MAXN];
bool g[MAXN][MAXN];
int mx[MAXN], my[MAXN];
int lx[MAXN], ly[MAXN];
int sx[MAXN], sy[MAXN];
int fx[MAXN], fy[MAXN];
int n;

int GetMaxMatch() {
    int i, j, p;
    i = 1;
    while (i <= n && mx[i] > 0) i++;
    while (i <= n) {
        memset(fx, 0, sizeof(fx));
        memset(fy, 0, sizeof(fy));
        sx[0] = 1;
        sx[1] = i;
        fx[i] = 1;
        sy[0] = 0;
        p = 1;
        for (j = 1; j <= n; j++) {
            if (g[i][j]) {
                fy[j] = i;
                sy[++sy[0]] = j;
            }
        }
        while (p <= sy[0]) {
            if (my[sy[p]] == 0) {
                i = sy[p];
                j = fy[i];
                while (mx[j] > 0) {
                    my[i] = j;
                    j = mx[j];
                    mx[my[j]] = i;
                    i = j;
                    j = fy[i];
                }
                mx[j] = i;
                my[i] = j;
                sx[0] = 0;
                break;
            }
            i = my[sy[p]];
            fx[i] = 1;
            sx[++sx[0]] = i;
            for (j = 1; j <= n; j++) {
                if (g[i][j] && fy[j] == 0) {
                    fy[j] = i;
                    sy[++sy[0]] = j;
                }
            }
            p++;
        }
        if (sx[0] == 0) {
            i = 1;
            while (i <= n && mx[i] > 0) i++;
        } else i = n + 1;
    }
    j = 0;
    for (i = 1; i <= n; i++) if (mx[i] > 0) j++;
    return j;
}

int GetPerfectMatch() {
    int i, j, min;
    for (i = 1; i <= n; i++) {
        lx[i] = 0;
        ly[i] = 0;
        for (j = 1; j <= n; j++) if (v[i][j] > lx[i]) lx[i] = v[i][j];
    }
    for (i = 1;i <= n; i++) {
        for (j = 1; j <= n; j++) {
            if (v[i][j] == lx[i]) g[i][j] = true;
            else g[i][j] = false;
        }
    }
    memset(mx, 0, sizeof(mx));
    memset(my, 0, sizeof(my));
    while (GetMaxMatch() < n) {
        j = sx[0];
        for (i = 1; i <= n; i++) if (fx[i] == 0) sx[++j] = i;
        j = sy[0];
        for (i = 1; i <= n; i++) if (fy[i] == 0) sy[++j] = i;
        min = 99999999;
        for (i = 1; i <= sx[0]; i++) {
            for (j = sy[0] + 1; j <= n; j++) {
                if (lx[sx[i]] + ly[sy[j]] - v[sx[i]][sy[j]] < min) {
                    min = lx[sx[i]] + ly[sy[j]] - v[sx[i]][sy[j]];
                }
            }
        }
        for (i = 1; i <= sx[0]; i++) lx[sx[i]] -= min;
        for (i = 1; i <= sy[0]; i++) ly[sy[i]] += min;
        for (i = 1; i <= sx[0]; i++) {
            for (j = sy[0] + 1; j <= n; j++) {
                if (lx[sx[i]] + ly[sy[j]] == v[sx[i]][sy[j]]) g[sx[i]][sy[j]] = true;
                else g[sx[i]][sy[j]] = false;
            }
        }
        for (i = sx[0] + 1; i <= n; i++) {
            for (j = 1; j <= sy[0]; j++) {
                if (lx[sx[i]] + ly[sy[j]] == v[sx[i]][sy[j]]) g[sx[i]][sy[j]] = true;
                else g[sx[i]][sy[j]] = false;
            }
        }
    }
    j = 0;
    for (i = 1; i <= n; i++) j += v[i][mx[i]];
    return j;
}
int main() {

    std::ios::sync_with_stdio(false);

    while (1) {
        cin >> n;
        if (!n) break;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                cin >> v[i][j];
            }
        }
        cout << GetPerfectMatch() << endl;
    }

    return 0;
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值