POJ 3723 Conscription(征兵) 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3723 Conscription(征兵) 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:http://poj.org/problem?id=3723

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.

题目大意:国王要征集一支部队保卫国家。他选定了N个女兵和M个男兵,每征集一个兵他要花10000RMB。他发现,某男兵和某女兵之间有某种联♂系,这可以少花一些钱就可征集到兵。但在征兵的时候,每一个兵只能使用一种关系来少花钱(啧啧)。这时国王向你求助,问他最少要花多少钱。

Input

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.

第一行:T,一共T组数据。

接下来T组数据,

第一行包括N,M,R

接下来的R行 包括Xi,Yi,Vi 表示如果招了第Xi个女兵,再招第Yi个男兵能省Vi元(同样表示如果招了第Yi个男兵,再招第Xi个女兵能也省Vi元)

1 ≤ N, M ≤ 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.

T行,表示每组数据的最终花费是多少(最终花费在maxlongint范围内)

Sample Input

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

Sample Output

71071
54223

Source

 
 
分析:
第一眼全机房都误判成了二分图......后来去了hzw学长的博客,发现居然只是一个最大生成树:(
最大生成树就不用多说,只要把最小生成树的比较规则改了就好了。
 
 
AC代码:
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 inline void read(int &x)
 7 {
 8     char ch = getchar();char c;x = 0;
 9     while(ch < 0 || ch > 9)    c = ch,ch = getchar();
10     while(ch >= 0 && ch <= 9)    x = x*10+ch-0,ch = getchar();
11     if(c == -)    x = -x;
12 }
13 const int MAXN = 30005;
14 int fa[MAXN];
15 struct edge
16 {
17     int f,t,v;
18 }e[MAXN << 1];
19 
20 struct edge tmp1,tmp2;
21 inline bool cmp(edge tmp1,edge tmp2)
22 {
23     return tmp1.v > tmp2.v ?1:0;
24 }
25 
26 int find(int x)
27 {
28     if(fa[x] == x)
29         return x;
30     return fa[x] = find(fa[x]);
31 }
32 
33 int merge(int x,int y)
34 {
35     x = find(x),y = find(y);
36     if(x != y)
37     {
38         fa[x] = y;
39         return 1;
40     }
41     else
42         return 0;
43 }
44 
45 int main()
46 {
47     int T,ans;
48     read(T);
49     int m,n,r,f,t,v;
50     for(int k = 1;k <= T;k ++)
51     {
52         ans = 0;
53         read(n),read(m),read(r);
54         for(int i = 1;i <= n+m;i ++)
55             fa[i] = i;
56         for(int i = 1;i <= r;i ++)
57         {
58             read(e[i].f),read(e[i].t),read(e[i].v);
59             e[i].f ++,e[i].t ++;
60             e[i].t += n;//保证从0~n-1是女兵,n~n+m-1是男兵 
61         }
62         sort(e+1,e+r+1,cmp);
63         for(int i = 1;i <= r;i ++)
64         {
65             bool is = merge(e[i].f,e[i].t);
66             if(is)    ans += e[i].v;
67         }
68         printf("%d\n",(n + m) * 10000 - ans);
69     }
70     return 0;
71 }

 

以上是关于POJ 3723 Conscription(征兵) 题解的主要内容,如果未能解决你的问题,请参考以下文章

Conscription(POJ 3723)

poj3723_Conscription

POJ3723--Conscription

POJ 3723 Conscription

Conscription POJ - 3723

POJ 3723 Conscription(最小生成树)