poj 3723 Conscription

题意:要征兵n个男兵和m个女兵,每个花费10000元,但是如果已经征募的男士兵中有和将要征募的女士兵关系好的,那么可以减少花费,给出关系,求最小花费。

解法:没有关系,需花费10000*(m+n)元,不断选取最大的关系值生成一颗最大生成树,再相减即可

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 #define r_max 50002
 7 #define v_max 20002
 8 int t;
 9 int n, m ,r ;
10 
11 struct Edge{
12     int start, to, cost;
13 };
14 Edge e[r_max];
15 
16 int cmp(const void *a, const void *b) {
17     Edge at = *(Edge *)a;
18     Edge bt = *(Edge *)b;
19     return bt.cost - at.cost;
20 }
21 int par[v_max];
22 int rank[v_max];
23 
24 void init(int n) {
25     for(int i = 0; i <= n; i++) {
26         par[i] = i;
27         rank[i] = 0;
28     }
29 }
30 
31 int find(int a) {
32     if(a == par[a]) {
33         return a;
34     }
35     else {
36         return par[a] = find(par[a]);
37     }
38 }
39 
40 int main(int argc, char const *argv[])
41 {
42     //freopen("input.txt","r",stdin);
43     scanf("%d",&t);
44     while(t--) {
45         scanf("%d %d %d",&n, &m, &r);
46         for(int i = 0; i < r; i++) {
47             scanf("%d %d %d",&e[i].start, &e[i].to, &e[i].cost);
48             e[i].to = e[i].to + n;
49         }
50         qsort(e, r, sizeof(Edge), cmp);
51         
52         init(n+m);
53         int cut = 0;
54         for(int i = 0; i < r; i++) {
55             int a = find(e[i].start);
56             int b = find(e[i].to);
57             if(a == b) {
58                 continue;
59             }
60             else {
61                 if(rank[a] < rank[b]) {
62                     par[a] = b;
63                 }
64                 else {
65                     par[b] = a;
66                     if(rank[a] == rank[b]) {
67                         rank[a]++;
68                     }
69                 }
70                 cut = cut + e[i].cost;
71             }
72         }
73         printf("%d\n",10000*(n+m) - cut);
74 
75     }
76     return 0;
77 }

也可以使用优先队列,不提倡,完全是练习

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <vector>
 4 #include <queue>
 5 
 6 using namespace std;
 7 #define r_max 50002
 8 #define v_max 20002
 9 int t;
10 int n, m ,r ;
11 
12 struct Edge{
13     int start, to, cost;
14 };
15 
16 int par[v_max];
17 int rank[v_max];
18 
19 void init(int n) {
20     for(int i = 0; i <= n; i++) {
21         par[i] = i;
22         rank[i] = 0;
23     }
24 }
25 
26 int find(int a) {
27     if(a == par[a]) {
28         return a;
29     }
30     else {
31         return par[a] = find(par[a]);
32     }
33 }
34 
35 struct cmp{
36     bool operator()(const Edge a,const Edge b){
37         return a.cost < b.cost;
38     }
39 };
40 priority_queue<Edge, vector<Edge>, cmp> que;
41 
42 int main(int argc, char const *argv[])
43 {
44     freopen("input.txt","r",stdin);
45     scanf("%d",&t);
46     while(t--) {
47         scanf("%d %d %d",&n, &m, &r);
48         for(int i = 0; i < r; i++) {
49             Edge e;
50             scanf("%d %d %d",&e.start, &e.to, &e.cost);
51             e.to = e.to + n;
52             que.push(e);
53         }
54         
55         init(n+m);
56         int cut = 0;
57         while(!que.empty()) {
58             Edge e = que.top();que.pop();
59             int a = e.start, b = e.to, c = e.cost;
60             printf("%d %d %d\n",a,b,c);
61             a = find(a);
62             b = find(b);
63             if(a == b) {
64                 continue;
65             }
66             else {
67                 if(rank[a] < rank[b]) {
68                     par[a] = b;
69                 }
70                 else {
71                     par[b] = a;
72                     if(rank[a] == rank[b]) {
73                         rank[a]++;
74                     }
75                 }
76                 cut = cut + c;
77             }
78         }
79         printf("%d\n",10000*(n+m) - cut);
80 
81     }
82     return 0;
83 }

 

posted @ 2016-08-22 10:49  Jason杰  阅读(167)  评论(0编辑  收藏  举报