码迷,mamicode.com
首页 > 其他好文 > 详细

Conscription

时间:2016-03-19 19:15:56      阅读:198      评论:0      收藏:0      [点我收藏+]

标签:

Conscription

TimeLimit:1000MS  MemoryLimit:65536K
64-bit integer IO format:%lld
Problem Description

Windy has a country, and he wants to build an army to protect his country. He has picked up N girls and M boys and wants to collect them to be his soldiers. To collect a soldier without any privilege, he must pay 10000 RMB. There are some relationships between girls and boys and Windy can use these relationships to reduce his cost. If girl x and boy y have a relationship d and one of them has been collected, Windy can collect the other one with 10000-d RMB. Now given all the relationships between girls and boys, your assignment is to find the least amount of money Windy has to pay. Notice that only one relationship can be used when collecting one soldier.

Input

The first line of input is the number of test case.
The first line of each test case contains three integers, NM and R.
Then R lines followed, each contains three integers xiyi and di.
There is a blank line before each test case.

1 ≤ NM ≤ 10000
0 ≤ R ≤ 50,000
0 ≤ xi < N
0 ≤ yi < M
0 < di < 10000

Output
For each test case output the answer in a single line.
SampleInput
2

5 5 8
4 3 6831
1 3 4583
0 0 6592
0 1 3063
3 3 4975
1 3 2049
4 2 2104
2 2 781

5 5 10
2 4 9820
3 2 6236
3 1 8864
2 4 8326
2 0 5156
2 0 1463
4 1 2439
0 4 4373
3 4 8889
2 4 3133
SampleOutput
71071
54223


题意:
  说是征兵,官方征兵每个人需要 10000 $, 但是因为 男女之间有些关系, 关系有个权值 d, 当钱用咯, 即是官方招那个人只需 10000 - d 的费用, 当然, 此人不能招两次。
不然也不是 最小生成树啦。囧

一开始, 脑子还没转动, 就想到了 有向图。 后来想了想不对, 这题用有向图做, 感觉很奇怪。 毕竟指的是不同的人。 有向图指的是同一点, 来往的权值不同。而这里的相同的男孩
女孩之间的权值是一样的。 所以有向图就不适合这问题了。  
想了想, 干脆 给男孩的 id 变到跟 女孩 的 id 完全不冲突为止。 就 男孩的 id += n( 女孩的总数 ) 咯!
再用并查集的知识AC就足够了。
code:
技术分享
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef struct node Node;
struct node
{
    int x;
    int y;
    int dropcost;
};

const int all = 20005;
int list[ all ];
Node M[ 3*all ];
int m, n, r, t, x_, y_;
ll ans;
void init( int t );
int make( int i );
bool cmp( Node , Node );

int main(void)
{
    scanf( "%d", &t );
    while( t -- ){
        scanf( "%d%d%d", &n, &m, &r );

        init( m+n );
        // 不依靠 男女之间 关系 总共需要多少钱
        ans = (m+n)*10000;
        for( int i=0; i < r; ++ i ){
            scanf( "%d%d%d", &M[i].x, &M[i].y, &M[i].dropcost );
            // 使男孩的 id 变到跟女孩的不冲突
            M[i].y += n;
        }

        // 最大 关系值 排序
        sort( M, M+r, cmp );
        for( int i=0; i < r; ++ i ){
            // 路径压缩。
            x_ = make( M[i].x );
            y_ = make( M[i].y );

            if( x_ != y_ ){
                list[x_] = y_;
                // 减去 男女 之间 关系钱
                ans -= M[i].dropcost;
            }
        }

        printf( "%lld\n", ans );
    }
    return 0;
}

void init( int t )
{
    for( int i=0; i <= t; ++ i ){
        list[i] = i;
    }
}

int make( int i )
{
    if( i != list[i] ){
        return list[i] = make( list[i] );
    }
    return i;
}

bool cmp( Node a, Node b )
{
    return a.dropcost > b.dropcost;
}
View Code

 

Conscription

标签:

原文地址:http://www.cnblogs.com/seana/p/5295777.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!