标签:
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.
The first line of input is the number of test case.
The first line of each test case contains three integers, N, M and R.
Then R lines followed, each contains three integers xi, yi and di.
There is a blank line before each test case.
1 ≤ N, M ≤ 10000
0 ≤ R ≤ 50,000
0 ≤ xi < N
0 ≤ yi < M
0 < di < 10000
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
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; }
标签:
原文地址:http://www.cnblogs.com/seana/p/5295777.html