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 }

 

posted @ 2017-12-12 21:12  qrfkickit  阅读(201)  评论(0编辑  收藏  举报