陕西省第一届ACM程序设计竞赛D题(最大生成树)

Problem 1268 - Donald’s company
Time Limit: 1000MS      Memory Limit: 65536KB      Difficulty:    
Total Submit: 3     Accepted: 3     Special Judge: No 
Description

Donald established a company. This company needs to employ M boys and N girls. The fee for employing one person is K RMB, but Donald finds that there exists a certain complex relationship between some boys and girls. The fee for employing can be decreased if this relationship can be fully made use of. Given the intensity of relationship between the ith boy and the jth girl is Rij, it needs the company K RMB to hire the ith boy or the jth girl first, and then it only needs (K- Rij) RMB to hire the jth girl or the ith boy.

All the X kinds of relationship between boys and girls are given and a person can be hired at most through one type of the relationship. Now, please help Donald to calculate the minimum expense he needs to spend to hire all the M boys and N girls.

Input
  The input consists of several test cases.
  The first line of the input contains a single integer T (0 < T ≤ 100), the number of test cases.
  Each case contains several lines.
   The first line of each case contains four integers M, N, K, X (0 < M,N ≤ 10000, 0 < K ≤ 10000, 0 ≤ X ≤ 50000), which meaning are described above.
   Then followed by X lines, each of which contains three integers i, j, Rij (0 ≤ i < M, 0 ≤ i
Output
  For each test case, output the least expense of hiring all the M boys and N girls.
Sample Input
3
2 2 50 2
0 1 10
1 0 20
2 2 100 4
0 0 10
0 1 20
1 0 30
1 1 40
4 3 10 6
0 2 2
1 2 4
3 1 5
2 0 1
1 1 3
3 2 2
Sample Output
170
310
55
Hint


http://acm.xidian.edu.cn/land/problem/detail?problem_id=1268

分析:

首先我们需要把题目抽象成图论模型,把有关系的都连上一条边,因为只能对应一种关系,所以它不会存在环,是一颗树,这个从样例数据也也能分析道,最后的答案是K*所有人-RR表示这颗树的边权,所以这是一道最大生成树问题。复杂度就是生成树的复杂度O(Mlog(M))


/*************************************************************************
* author:crazy_石头
* algorithm:MST
* date:2013/09/29
**************************************************************************/
#include
#include
#include

using namespace std;

#define MAX 50000
 

struct data
{
    int a,b,val;
}x[MAX];
 

struct USFtree
{
    int p,rank;
}note[MAX*2];
 

void makeset(int m)     //点的初始化
{
    note[m].p=m;
    note[m].rank=0;
}

int find(int m)      //并查集,查找祖先节点
{
    while(m!=note[m].p)
        m=note[m].p;
    return m;
}

void union2(int m,int n)    //并查集,两颗子树按秩合并;也可以路径压缩的;
{
    m=find(m);
    n=find(n);
    if(n==m)
        return;
    else
    {
        if(note[n].rank>note[m].rank)
            note[m].p=n;
        else
        {
            note[n].p=m;
            if(note[n].rank==note[m].rank)
                note[m].rank++;
        }
    }
}

bool cmp(const data &a, const data &b)
{
    return a.val>b.val;
}

int main()
{
    int n,m,i,t,cas,k,r,cnt;
    scanf("%d",&cas);
    while(cas--)
    {
        memset(note,0,sizeof(note));
        cnt=0;
        scanf("%d%d%d%d",&n,&m,&k,&r);
        for(i=0;i

你可能感兴趣的:(ACM_图论)