zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",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
    ",10000*(n+m) - cut);
    80 
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    Windows10 ntoskrnl.exe占用大量的磁盘空间(100%)
    Windows10 正式企业版激活
    edit-distance
    climbing-stairs
    minimum-path-sum
    unique-paths-II
    unique-paths
    剑指 Offer 42. 连续子数组的最大和
    剑指 Offer 54. 二叉搜索树的第k大节点
    矩阵中的路径
  • 原文地址:https://www.cnblogs.com/jasonJie/p/5794752.html
Copyright © 2011-2022 走看看