24h購物| | PChome| 登入
2013-10-02 14:34:58| 人氣1,203| 回應0 | 上一篇 | 下一篇

[UVA][二分圖檢查MST] 11267 - The Hire-a-Coder Business Model

推薦 0 收藏 0 轉貼0 訂閱站台

Problem H
The ‘Hire-a-Coder’ Business Model
Input: Standard Input

Output: Standard Output

 

As some other websites, ‘Hire-a-Coder’ is a new website that works as an agent between custom software buyers & freelance software developers. According to the ‘Hire-a-Coder’ business model, a number of clients are registered in the system. Some of them are software buyers. They post custom software projects on the site. Then the coders bid on the projects & each of the projects is assigned to a single particular coder after the biddings & dealings. Any buyer may have more than one open project at a time. Similarly any coder can take up more than a single project at any time. But no coder is allowed to take multiple projects from the same buyer at a time. The site works as a medium in the total procedure. Now, if a coder successfully completes his assigned project & the buyer accepts his work, ‘Hire-a-Coder’ gets some commission for that. But if the coder fails to complete a project or satisfy the client with his work, the company has to pay a penalty to the buyer thus suffering a loss.

 

Recently it is found out that there are a number of fake coders that take up a project but never finish their work eventually causing the company a good amount of loss. So, they need someone to advise them which of the possible project assignments are to make & which are to avoid in order to minimize their loss.

 

Assume, all the registered clients of the company are denoted by a unique positive integer number between 1 & N. By the help of a great fortune-teller, they have already tabulated the future of assigning all possible buyer-coder pairs. You can assume that assigning any project from a particular buyer to a particular coder has the same future. In their tabulation, if a coder fails to do a project from a buyer, a positive integer value is assigned to this particular buyer-coder pair. The value indicates the amount of loss the company is going to suffer if they pair-up these two clients. On the other hand, in case of a successful completion of a project from a buyer-coder pair, a negative integer value is assigned to this pair which denotes negative loss i.e. amount of profit.

 

You are assured that, every single individual in the community has a communication link to all other people in this community, not necessarily through direct acquaintance. The link may well be via one or more other people. Also note that, if ‘A’ knows ‘B’ then ‘B’ always knows ‘A’.

 

There’s one more problem. You have the pairing information for all those N people but you don’t know which of them are buyers & which of them are coders. But you know that, all the registered clients are either a buyer or a coder & there’s no one who is a buyer & a coder simultaneously. If the data for any test case violates this assumption, print “Invalid data, Idiot!” & stop processing that case further.

 

Now, bearing all these factors in mind, you are to select a subset of the possible pairings so that if the company makes strictly those assignments, their loss is minimum possible. Also, you have to choose the subset so that every single person still has a direct / indirect communication link to all other people.

 

Input

 

Every test case starts with a single positive integer N (2<=N<=200) which is the number of registered clients. The second line has another positive integer E (1<=N<=11000), the number of pairs tabulated by the fortune-teller. Each of the next E lines contains 3 integers A,B & C which means, if the company pairs A with B, they will end up in a  loss with amount C. (1<=A,B<=N and -1000<=C<=1000). The last test case will be followed immediately by a single line containing a 0. This line indicates the end of file.

 

Output

 

If the there is any inconsistency in the data (as described in the statement) print “Invalid data, Idiot!” in a single line. Otherwise, print the minimum possible loss the company can afford without disconnecting the social network.

 

Sample Input

Sample Output

6

9

1 4 1

2 4 2

3 4 3

1 5 2

2 5 3

3 5 2

1 6 3

2 6 1

3 6 2

6

10

1 2 3

1 4 1

2 4 2

3 4 3

1 5 2

2 5 3

3 5 2

1 6 3

2 6 1

3 6 2

4

4

1 3 5

1 4 -3

2 3 2

2 4 -6

0

8

Invalid data, Idiot!

-7

 


Problemsetter: Mohammad Mahmudur Rahman

Special Thanks To: Manzurur Rahman Khan

題目描述:

現在有 N 個人,每個人要不是 buyer 不然就是 coder。

但是題目沒有說明每個人扮演的角色,只知道如果他們如果指派程式給當 coder 的做的話,會有利益關係。

算命師要對所有人都回答他們應該要跟誰合作,因此每個人都有工作。

一個 coder 可以同時做很多項工作,輸入不會存在一個 coder 與一個 buyer 有多項關係。

求最少損失。

題目解法:


首先,必須先用 BFS 檢查是否為二分圖,以符合題目要求。

接下來處理 MST 的工作,不過這裡比較特別:

由於負數是賺錢,這條邊是必然要選的,而虧損的邊則是選越少越好,但又要讓每個人有工作 => MST 無誤。


#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
struct edge {
    int x, y, v;
    bool operator<(const edge &a) const {
        return v < a.v;
    }
    edge(int a=0, int b=0, int c=0):
        x(a), y(b), v(c) {}
};
edge D[11005];
vector<int> g[205];
int check(int n) {
    int color[205] = {}, used[205] = {};
    int i, j, k, tn;
    queue<int> Q;
    Q.push(1);
    while(!Q.empty()) {
        tn = Q.front(), Q.pop();
        for(i = 0; i < g[tn].size(); i++) {
            if(used[g[tn][i]] == 0) {
                used[g[tn][i]] = 1;
                color[g[tn][i]] = !color[tn];
                Q.push(g[tn][i]);
            } else {
                if(color[g[tn][i]] == color[tn])
                    return 0;
            }
        }
    }
    return 1;
}
int p[205], rank[205];
int findp(int x) {
    return p[x] == x ? x : p[x] = findp(p[x]);
}
int joint(int x, int y) {
    x = findp(x), y = findp(y);
    if(x == y)    return 0;
    if(rank[x] > rank[y]) {
        rank[x] += rank[y], p[y] = x;
    } else {
        rank[y] += rank[x], p[x] = y;
    }
    return 1;
}
int MST(int n, int m) {
    sort(D, D+m);
    int i, j, k;
    int cost = 0;
    for(i = 1; i <= n; i++)
        rank[i] = 1, p[i] = i;
    for(i = 0; i < m; i++) {
        if(joint(D[i].x, D[i].y) || D[i].v < 0) {
            cost += D[i].v;
        }
    }
    return cost;
}
int main() {
    int n, m;
    int i, j, k;
    int x, y, v;
    while(scanf("%d %d", &n, &m) == 2 && n+m) {
        for(i = 1; i <= n; i++)
            g[i].clear();
        for(i = 0; i < m; i++) {
            scanf("%d %d %d", &x, &y, &v);
            g[x].push_back(y);
            g[y].push_back(x);
            D[i] = edge(x, y, v);
        }
        if(check(n) == 0) {
            puts("Invalid data, Idiot!");
            continue;
        }
        int ret = MST(n, m);
        printf("%d\n", ret);
    }
    return 0;
}

台長: Morris
人氣(1,203) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 教育學習(進修、留學、學術研究、教育概況) | 個人分類: UVA |
此分類下一篇:[UVA][四分樹&DP] 12074 - The Ultimate Bamboo Eater
此分類上一篇:[UVA][SCC] 1243 - Polynomial-time Reductions

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文