POJ 3723 Conscription (Kruskal并查集求最小生成树)

Conscription

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14661   Accepted: 5102

Description

Windy has a country, and he wants to build an army to protect his country. He has picked up N girls and M boys and wants to collect them to be his soldiers. To collect a soldier without any privilege, he must pay 10000 RMB. There are some relationships between girls and boys and Windy can use these relationships to reduce his cost. If girl x and boy y have a relationship d and one of them has been collected, Windy can collect the other one with 10000-d RMB. Now given all the relationships between girls and boys, your assignment is to find the least amount of money Windy has to pay. Notice that only one relationship can be used when collecting one soldier.

Input

The first line of input is the number of test case.
The first line of each test case contains three integers, NM and R.
Then R lines followed, each contains three integers xiyi and di.
There is a blank line before each test case.

1 ≤ NM ≤ 10000
0 ≤ R ≤ 50,000
0 ≤ xi < N
0 ≤ yi < M
0 < di < 10000

Output

For each test case output the answer in a single line.

Sample Input

2

5 5 8
4 3 6831
1 3 4583
0 0 6592
0 1 3063
3 3 4975
1 3 2049
4 2 2104
2 2 781

5 5 10
2 4 9820
3 2 6236
3 1 8864
2 4 8326
2 0 5156
2 0 1463
4 1 2439
0 4 4373
3 4 8889
2 4 3133

Sample Output

71071
54223


题意:有N+M个顶点,边:两个顶点之间的亲密度。    单独获取某个顶点的花费是10000;    如果两个顶点的亲密度为x,我已经获取了其中一个顶点,那么获取另一个顶点花费10000-x。   现在你要把所有的顶点全部获取,算出最小花费。


【方法1】我们可以想到这是一个森林,我们需要求最小生成树(最小花费)。由于权值x越大花费越小,所以我们把权值取反为-x,求出最小生成树(通过关系获取比直接获取可以少花费多少),然后再加上每个点花费的10000,就得到了我们的总花费。


【方法2】你可能会说,直接把权值设置为10000-x也可以写,但是考虑到我们求出最小生成树之后还要再求出连通分量,总花费 = 最小生成树(通过关系获取)+ 连通分量*10000。

明显比前一种算法复杂度要高(主要是我还不会写连通分量)。

不过不会写不要紧,我们可以用Kruskal算法用到的并查集,并查集中的parent数组保存的就是属于哪棵树,所以算一下parent中有几个不同的值就可以得到连通分量。

Kruskal算法讲解:http://www.cnblogs.com/zhangjiuding/p/7796526.html

代码:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <set>
#include <queue>
using namespace std;
typedef long long ll;
#define MAX_N 20010
#define MAX_E 50010
#define INF 2147483647

struct edge {
    int u,v,cost;
}; 

bool cmp(const edge & e1,const edge &e2){
    return e1.cost < e2.cost;
}

edge es[MAX_E];  //边集
int V,E;   //顶点数和边数 

int par[MAX_N]; //par[i]表示i节点的父节点
int rank[MAX_N]; // 树的高度 

//初始化n个元素
void init(int n){
    for(int i = 0;i < n; i++){
        par[i] = i;
        rank[i] = 0;
    }
} 

//查询包含x节点的树的根
int find(int x){
    if(par[x] == x) return x;
    else return par[x] = find(par[x]);
}

//合并 x和y所属的集合
void unite(int x,int y){
    x = find(x);
    y = find(y);
    if(x == y) return;

    if(rank[x] < rank[y]){
        par[x] = y;
    }else{
        par[y] = x;
        if(rank[x] == rank[y]) rank[x]++;
    }
}

//判断x和y是否属于同一个集合
bool same(int x,int y){
    return find(x) == find(y);
}

int kruskal(){
  sort(es, es + E, cmp);
  init(V);
  int res = 0;
  for(int i = 0;i < E; i++ ){
      edge e = es[i];
      if(!same(e.u,e.v)){
          unite(e.u, e.v);
          res += e.cost;
        }
    }
    return res;
} 

int main(){
    int t;
    cin >> t;
    while(t--){

        int n,m,r;
        cin >> n >> m >> r;
        V = n+m;
        E = r;
        for(int i = 0;i < r; i++){
            edge e;
            scanf("%d%d%d",&e.u,&e.v,&e.cost);
            e.cost = - e.cost;
            e.v += n;
            es[i] = e;
        }

      cout << V*10000 + kruskal() << endl;
  }
    return 0;
} 

 
时间: 2024-11-05 15:48:33

POJ 3723 Conscription (Kruskal并查集求最小生成树)的相关文章

POJ 1611 The Suspects (并查集求数量)

Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. To minimize transmission to others, the best strategy is to separate the suspects from others. In t

poj 3723 Conscription(最小生成树拓展)

Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7702   Accepted: 2667 Description Windy has a country, and he wants to build an army to protect his country. He has picked up N girls and M boys and wants to collect them to be

[ACM] POJ 1611 The Suspects (并查集,输出第i个人所在集合的总人数)

The Suspects Time Limit: 1000MS   Memory Limit: 20000K Total Submissions: 21586   Accepted: 10456 Description Severe acute respiratory syndrome (SARS), an atypical pneumonia of unknown aetiology, was recognized as a global threat in mid-March 2003. T

poj 3723 Conscription 【最大生成树|最大权森林】

题目:poj 3723 Conscription 题意:要征兵n个男兵和m个女兵,每个花费10000元,但是如果已经征募的男士兵中有和将要征募的女士兵关系好的,那么可以减少花费,给出关系,求最小花费. 分析:这个题目初始一个是个二分图,以为可以从这里入手,但是这个题目这个性质没用. 初始花费没人10000,那么减去其中有关系的就是当前的花费. 要是花费最少,那么减去的最大即可,又因为没人只征募一次,即最多选择一个,所以减去一个最大生成树就ok AC代码: #include <cstdio> #

SDUT 2933-人活着系列之Streetlights(最小生成树Kruskal+并查集实现)

人活着系列之Streetlights Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 人活着如果是为了家庭,亲情----可以说是在这个世界上最温暖人心的,也是最让人放不下的,也是我在思索这个问题最说服自己接受的答案.对,也许活着是一种责任,为了繁殖下一代,为了孝敬父母,男人要养家糊口,女人要生儿育女,就这样循环的过下去,但最终呢?还是劳苦愁烦,转眼成空呀! 为了响应政府节约能源的政策,某市要对路灯进行改革,已知该市有n个城镇,

POJ 2524 Ubiquitous Religions (幷查集)

Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23090   Accepted: 11378 Description There are so many different religions in the world today that it is difficult to keep track of them all. You are interested in findi

[ACM] POJ 3295 Ubiquitous Religions (并查集)

Ubiquitous Religions Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 23093   Accepted: 11379 Description There are so many different religions in the world today that it is difficult to keep track of them all. You are interested in findi

poj 1456 Supermarket (贪心+并查集)

# include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int fa[10010]; struct node { int p; int d; }; struct node a[10010]; bool cmp(node a1,node a2)//利润从大到小 { return a1.p>a2.p; } int find(int x) { if(fa[x]

poj 2513 Colored Sticks 并查集 字典树 欧拉回路判断

点击打开链接题目链接 Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 30273   Accepted: 8002 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sti