Assignment HDU - 2853(求最小改變邊數)


Assignment

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1698    Accepted Submission(s): 901


Problem Description
Last year a terrible earthquake attacked Sichuan province. About 300,000 PLA soldiers attended the rescue, also ALPCs. Our mission is to solve difficulty problems to optimization the assignment of troops. The assignment is measure by efficiency, which is an integer, and the larger the better.
We have N companies of troops and M missions, M>=N. One company can get only one mission. One mission can be assigned to only one company. If company i takes mission j, we can get efficiency Eij. 
We have a assignment plan already, and now we want to change some companies’ missions to make the total efficiency larger. And also we want to change as less companies as possible.
 

 

Input
For each test case, the first line contains two numbers N and M. N lines follow. Each contains M integers, representing Eij. The next line contains N integers. The first one represents the mission number that company 1 takes, and so on.
1<=N<=M<=50, 1<Eij<=10000.
Your program should process to the end of file.
 

 

Output
For each the case print two integers X and Y. X represents the number of companies whose mission had been changed. Y represents the maximum total efficiency can be increased after changing.
 

 

Sample Input
3 3 2 1 3 3 2 4 1 26 2 2 1 3 2 3 1 2 3 1 2 3 1 2
 

 

Sample Output
2 26 1 2
 

 

Source
 

 

Recommend
gaojie
 
關鍵是求最小的改變 (盡量減少公司改變任務 且 使效率最大)
做法就和求最小割邊的條數一樣
我們把每個w都乘上100(大於n即可 一會再解釋)
然后把對每個公司原分配的w + 1
那么在同等條件下 原分配的任務是不是  就會優先被選擇
而乘100
最后求出max_value % 100 是不是就是原分配的任務 在最后分配中保留的個數  (因為除了原分配的任務 都是100的倍數啊)
那么max_value / 100 是不是就是最后分配效率的真實值 
有人可能會問有的值不是+ 1 了嗎
就算n個數 全 + 1, 那是不是 + n  , n 除一個大於n的數是不是就是0
這就是為什么要乘一個比n大的數的原因
然后就是裸km了
 
#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <bitset>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define rb(a) scanf("%lf", &a)
#define rf(a) scanf("%f", &a)
#define pd(a) printf("%d\n", a)
#define plld(a) printf("%lld\n", a)
#define pc(a) printf("%c\n", a)
#define ps(a) printf("%s\n", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _  ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = 55, INF = 0x7fffffff;
int n, m;
int usedx[maxn], usedy[maxn], w[maxn][maxn], bx[maxn], by[maxn], cx[maxn], cy[maxn], slack[maxn];
int nx, ny, minn, max_value;

int dfs(int u)
{
    usedx[u] = 1;
    for(int i=1; i<=ny; i++)
    {
        if(usedy[i] == -1)
        {
            int t = bx[u] + by[i] - w[u][i];
            if(t == 0)
            {
                usedy[i] = 1;
                if(cy[i] == -1 || dfs(cy[i]))
                {
                    cy[i] = u;
                    cx[u] = i;
                    return 1;
                }
            }
            else
                slack[i] = min(slack[i], t);
        }
    }
    return 0;
}

int km()
{
    mem(cx, -1);
    mem(cy, -1);
    mem(bx, -1);
    mem(by, 0);
    for(int i=1; i<=nx; i++)
        for(int j=1; j<=ny; j++)
            bx[i] = max(bx[i], w[i][j]);
    for(int i=1; i<=nx; i++)
    {
        for(int j=1; j<=ny; j++)
            slack[j] = INF;
        while(1)
        {
            mem(usedx, -1);
            mem(usedy, -1);
            if(dfs(i)) break;
            int d = INF;
            for(int j=1; j<=ny; j++)
                if(usedy[j] == -1)
                    d = min(d, slack[j]);
            for(int j=1; j<=nx; j++)
                if(usedx[j] != -1) bx[j] -= d;
            for(int j=1; j<=ny; j++)
                if(usedy[j] != -1) by[j] += d;
                else
                    slack[j] -= d;
        }
    }
    max_value = 0;
    for(int i=1; i<=nx; i++)
        if(cx[i] != -1)
            max_value += w[i][cx[i]];
    return max_value;
}


int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        nx = n, ny = m;
        int tmp;
        rap(i, 1, n)
            rap(j, 1, m)
            {
                rd(w[i][j]);
                w[i][j] *= 100;
            }
        int pre_sum = 0;
        rap(i, 1, n)
        {
            rd(tmp);
            pre_sum += w[i][tmp];
            w[i][tmp] += 1;
        }
        max_value = km();
        printf("%d %d\n", n - max_value % 100, max_value / 100 - pre_sum / 100);

    }

    return 0;
}

 

Assignment

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1698    Accepted Submission(s): 901


Problem Description
Last year a terrible earthquake attacked Sichuan province. About 300,000 PLA soldiers attended the rescue, also ALPCs. Our mission is to solve difficulty problems to optimization the assignment of troops. The assignment is measure by efficiency, which is an integer, and the larger the better.
We have N companies of troops and M missions, M>=N. One company can get only one mission. One mission can be assigned to only one company. If company i takes mission j, we can get efficiency Eij. 
We have a assignment plan already, and now we want to change some companies’ missions to make the total efficiency larger. And also we want to change as less companies as possible.
 

 

Input
For each test case, the first line contains two numbers N and M. N lines follow. Each contains M integers, representing Eij. The next line contains N integers. The first one represents the mission number that company 1 takes, and so on.
1<=N<=M<=50, 1<Eij<=10000.
Your program should process to the end of file.
 

 

Output
For each the case print two integers X and Y. X represents the number of companies whose mission had been changed. Y represents the maximum total efficiency can be increased after changing.
 

 

Sample Input
3 3 2 1 3 3 2 4 1 26 2 2 1 3 2 3 1 2 3 1 2 3 1 2
 

 

Sample Output
2 26 1 2
 

 

Source
 

 

Recommend
gaojie

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com