MST:Conscription(POJ 3723)

                 

               男女搭配,干活不累

  题目大意:需要招募女兵和男兵,每一个人都的需要花费1W元的招募费用,但是如果有一些人之间有亲密的关系,那么就会减少一定的价钱,如果给出1~9999的人之间的亲密关系,现在要你求招募所有人的时候,最少的价格?

  看似这一题要用到二分图,其实根本用不上,我们仔细想一下我们如果把所有的男和女都看成人的话,那么其实我们就是要求这些关系的最大值的负值(也就是最小生成树)

  这样一看,这题其实很裸,要注意区分男和女就行(别搞错男女了,不然就RE了),男的点的位置就看成是女的总数+男的坐标就可以了额

  

  1 #include <iostream>
  2 #include <functional>
  3 #include <algorithm>
  4 #define MAX 20005
  5 #define MAX_E 50005
  6 
  7 using namespace std;
  8 typedef int Position;
  9 typedef struct _edge
 10 {
 11     int cost;
 12     int from;
 13     Position to;
 14 }Edge_Set;
 15 int fcomp(const void *a, const void *b)
 16 {
 17     return (*(Edge_Set *)a).cost - (*(Edge_Set *)b).cost;
 18 }
 19 
 20 static Edge_Set Edge[MAX_E];
 21 Position V_Set[MAX];
 22 
 23 void Kruskal(const int, const int);
 24 Position Find(Position);
 25 bool If_Same(Position, Position);
 26 void Union(Position, Position);
 27 
 28 int main(void)
 29 {
 30     int test_case, men_sum, women_sum, R_sum, cost_tmp;
 31     Position from, to;
 32     scanf("%d", &test_case);
 33 
 34     while (test_case--)
 35     {
 36         //这一题不用二分图的方法,直接上MST
 37         scanf("%d%d%d", &women_sum, &men_sum, &R_sum);
 38         for (int i = 0; i < R_sum; i++)
 39         {
 40             scanf("%d%d%d", &from, &to, &cost_tmp);//男生的坐标要加上女生总数
 41             Edge[i].from = from; Edge[i].to = to + women_sum; Edge[i].cost = -cost_tmp;//存负的
 42         }
 43         Kruskal(men_sum + women_sum, R_sum);
 44     }
 45     return 0;
 46 }
 47 
 48 Position Find(Position x)
 49 {
 50     if (V_Set[x] < 0)
 51         return x;
 52     else return V_Set[x] = Find(V_Set[x]);
 53 }
 54 
 55 bool If_Same(Position x, Position y)
 56 {
 57     Position px, py;
 58     px = Find(x); py = Find(y);
 59     return px == py;
 60 }
 61 
 62 void Union(Position x, Position y)
 63 {
 64     Position px, py;
 65     px = Find(x); py = Find(y);
 66 
 67     if (px != py)
 68     {
 69         if (V_Set[px] < V_Set[py])
 70         {
 71             V_Set[px] += V_Set[py];
 72             V_Set[py] = px;
 73         }
 74         else
 75         {
 76             V_Set[py] += V_Set[px];
 77             V_Set[px] = py;
 78         }
 79     }
 80 }
 81 
 82 void Kruskal(const int n, const int edge_sum)
 83 {
 84     //初始化查并集
 85     fill(V_Set, V_Set + n, -1);
 86     qsort(Edge, edge_sum, sizeof(Edge_Set), fcomp);//把边排个大小
 87 
 88     Edge_Set e;
 89     long long ans = 0;
 90     for (int i = 0; i < edge_sum; i++)
 91     {
 92         e = Edge[i];
 93         if (!If_Same(e.from, e.to))
 94         {
 95             Union(e.from, e.to);
 96             ans += e.cost;
 97         }
 98     }
 99     printf("%lld\n", (long long)n * 10000 + ans);
100 }

posted @ 2015-11-08 22:44  PhiliAI  阅读(312)  评论(0编辑  收藏  举报