此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接: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
POJ Monthly Contest – 2009.04.05, windy7926778
分析:
第一眼全机房都误判成了二分图......后来去了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 }