poj 3723 Conscription
题意:
招募n个男兵和m个女兵,招募一个人的钱是10000,但是男兵与女兵之间存在亲密关系。
如果招募的一个兵与已经招募的兵之间存在亲密关系,那么招募的钱就是10000 -(亲密系数)。
求最少需要多少钱。
思路:
求最大生成森林。
坑:
运算符重载到底怎么回事啊Orz
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 #include <set> 6 using namespace std; 7 8 struct node 9 { 10 int x,y; 11 int w; 12 13 bool operator < (const node& rhs) const 14 { 15 return w > rhs.w; 16 } 17 } a[50005]; 18 19 int par[20005]; 20 int ran[20005]; 21 22 set<int> s; 23 24 void init(int n) 25 { 26 for (int i = 0;i <= n;i++) 27 { 28 par[i] = i; 29 ran[i] = 0; 30 } 31 32 s.clear(); 33 } 34 35 int fin(int x) 36 { 37 if (x == par[x]) return x; 38 else return par[x] = fin(par[x]); 39 } 40 41 void unit(int x,int y) 42 { 43 x = fin(x); 44 y = fin(y); 45 46 if (x == y) return; 47 48 if (ran[x] < ran[y]) 49 { 50 par[x] = y; 51 } 52 else 53 { 54 par[y] = x; 55 56 if (ran[x] == ran[y]) ran[x]++; 57 } 58 } 59 60 int main() 61 { 62 int t; 63 64 scanf("%d",&t); 65 66 while (t--) 67 { 68 int n,m,r; 69 70 scanf("%d%d%d",&n,&m,&r); 71 72 init(m+n); 73 74 for (int i = 0;i < r;i++) 75 { 76 int x,y,w; 77 78 scanf("%d%d%d",&x,&y,&w); 79 80 x += m; 81 82 a[i].x = x; 83 a[i].y = y; 84 a[i].w = w; 85 } 86 87 sort(a,a+r); 88 89 int ans = 0; 90 91 for (int i = 0;i < r;i++) 92 { 93 int x = a[i].x,y = a[i].y; 94 95 if (fin(x) == fin(y)) continue; 96 97 ans += 10000 - a[i].w; 98 99 unit(x,y); 100 } 101 102 for (int i = 0;i < m + n;i++) 103 { 104 int x = fin(i); 105 s.insert(x); 106 } 107 108 ans += s.size() * 10000; 109 110 printf("%d\n",ans); 111 } 112 113 return 0; 114 }
康复训练中~欢迎交流!