题目大意:需要招募女兵和男兵,每一个人都的需要花费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 ", (long long)n * 10000 + ans); 100 }