Conscription

Descriptions

需要征募女兵N人,男兵M人。 每招募一个人需要花费10000美元。 如果已经招募的人中有一些关系亲密的人,那么可以少花一些钱。 给出若干男女之前的1 ~ 9999 之间的亲密度关系, 招募某个人的费用是 10000 - (已经招募了的人中和自己的亲密度的最大值)。 要求通过适当的招募顺序使得招募所有人所花费的费用最小。

Input

输入N, M, R;
接下来输入R行 (x, y, d) 表示第 x 号男兵和第 y 号女兵之间的亲密度是 d


Output

输入最小花费的值。


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

题目链接

https://vjudge.net/problem/POJ-3723

把人看成点,关系看作边,转化为求解无向图的最大权森林问题,这个问题又可以通过把所有边取反之后用最小生成树的算法求解

典型的kruskal算法

注意要用scanf printf

AC代码

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS \
ios_base::sync_with_stdio(); \
cin.tie();
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x, y) memset(x, y, sizeof(x))
#define Maxn 1000000 + 10
using namespace std;
int N, M, R;
int x[Maxn], y[Maxn], d[Maxn];//男孩 女孩 关系度
struct edge
{
int u, v, cost;//u到v的距离为cost
};
bool cmp(const edge &e1, const edge &e2)//从小到大排序
{
return e1.cost < e2.cost;
}
edge es[Maxn];
int par[Maxn];
void init(int n)//初始化并查集
{
for (int i = ; i <= n; i++)
par[i] = i;
}
int findr(int x)//寻根
{
if (par[x] == x)
return x;
return par[x] = findr(par[x]);
}
void unite(int x, int y)//合并
{
x = findr(x);
y = findr(y);
if (x == y)
return;
par[x] = y;
}
bool same(int x, int y)//判断根是否相同
{
return findr(x) == findr(y);
}
int kruskal(int V, int E)//kruskal算法求最小生成树
{
sort(es, es + E, cmp);
init(V);
int res = ;
for (int i = ; 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;
scanf("%d", &T);
while (T--)//T组测试样例
{
scanf("%d%d%d", &N, &M, &R);//存数据
for (int i = ; i < R; i++)
scanf("%d%d%d", &x[i], &y[i], &d[i]);
int V, E;
V = N + M;//顶点个数
E = R;//边个数
for (int i = ; i < E; i++)//存入结构体
{
es[i] = (edge){
x[i], N + y[i], -d[i]};
}
printf("%d\n", * (N + M) + kruskal(V, E));
}
return ;
}
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define IOS                       \
    ios_base::sync_with_stdio(); \
    cin.tie();
#define Mod 
#define eps 1e-
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x, y) memset(x, y, sizeof(x))
#define Maxn  + 
using namespace std;
int N, M, R;
int x[Maxn], y[Maxn], d[Maxn];//男孩 女孩 关系度
struct edge
{
    int u, v, cost;//u到v的距离为cost
};
bool cmp(const edge &e1, const edge &e2)//从小到大排序
{
    return e1.cost < e2.cost;
}
edge es[Maxn];
int par[Maxn];
void init(int n)//初始化并查集
{
    for (int i = ; i <= n; i++)
        par[i] = i;
}
int findr(int x)//寻根
{
    if (par[x] == x)
        return x;
    return par[x] = findr(par[x]);
}
void unite(int x, int y)//合并
{
    x = findr(x);
    y = findr(y);
    if (x == y)
        return;
    par[x] = y;
}
bool same(int x, int y)//判断根是否相同
{
    return findr(x) == findr(y);
}
int kruskal(int V, int E)//kruskal算法求最小生成树
{
    sort(es, es + E, cmp);
    init(V);
    int res = ;
    for (int i = ; 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;
    scanf("%d", &T);
    while (T--)//T组测试样例
    {
        scanf("%d%d%d", &N, &M, &R);//存数据
        for (int i = ; i < R; i++)
            scanf("%d%d%d", &x[i], &y[i], &d[i]);
        int V, E;
        V = N + M;//顶点个数
        E = R;//边个数
        for (int i = ; i < E; i++)//存入结构体
        {
            es[i] = (edge){
                x[i], N + y[i], -d[i]};
        }
        printf("%d\n",  * (N + M) + kruskal(V, E));
    }
    return ;
}

【POJ - 3723 】Conscription(最小生成树)的更多相关文章

  1. POJ 3723 Conscription 最小生成树

    题目链接: 题目 Conscription Time Limit: 1000MS Memory Limit: 65536K 问题描述 Windy has a country, and he wants ...

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

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

  3. POJ 3723 Conscription【最小生成树】

    题意: 征用一些男生和女生,每个应都要给10000元,但是如果某个男生和女生之间有关系,则给的钱数为10000减去相应的亲密度,征集一个士兵时一次关系只能使用一次. 分析: kruskal求最小生成树 ...

  4. poj - 3723 Conscription(最大权森林)

    http://poj.org/problem?id=3723 windy需要挑选N各女孩,和M各男孩作为士兵,但是雇佣每个人都需要支付10000元的费用,如果男孩x和女孩y存在亲密度为d的关系,只要他 ...

  5. POJ 3723 Conscription

    Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6325   Accepted: 2184 Desc ...

  6. POJ 3723 Conscription(并查集建模)

    [题目链接] http://poj.org/problem?id=3723 [题目大意] 招募名单上有n个男生和m个女生,招募价格均为10000, 但是某些男女之间存在好感,则招募的时候, 可以降低与 ...

  7. POJ 3723 Conscription MST

    http://poj.org/problem?id=3723 题目大意: 需要征募女兵N人,男兵M人,没征募一个人需要花费10000美元,但是如果已经征募的人中有一些关系亲密的人,那么可以少花一些钱, ...

  8. POJ 3723 征兵问题(最小生成树算法的应用)

    Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15923   Accepted: 5510 Des ...

  9. Conscription(POJ 3723)

    原题如下: Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16584   Accepted: 57 ...

随机推荐

  1. PythonI/O进阶学习笔记_2.魔法函数

    前言: 本文一切观点和测试代码是在python3的基础上. Content: 1.什么是魔法函数,魔法函数__getitem__在python中应用. 2.python的数据模型和数据模型这种设计对p ...

  2. Java生产者消费者的三种实现

    Java生产者消费者是最基础的线程同步问题,java岗面试中还是很容易遇到的,之前没写过多线程的代码,面试中被问到很尬啊,面完回来恶补下.在网上查到大概有5种生产者消费者的写法,分别如下. 用sync ...

  3. vue当图片加载失败时,用一个默认图片替换;

    原理就是给img绑定error事件,替换原有的src地址. 首先在data中创建一个defaultImg(随便起的),里面的值是该默认图片的地址: 在html页面的img标签上绑定该属性 这样默认图片 ...

  4. LiteORM-For-DotNet,我的第一个开源库

    这是一个DotNet轻量级ORM框架,解决C#.Net开发过程中重复繁琐的数据库CURD操作. 前言 因工作中接手的.net项目,源码里面都用了动软代码生成的源码做为数据库操作类库.其中,有些根本就没 ...

  5. xib上的控件属性为什么要使用weak

    常规中,从xib拖出一个控件时,系统会自动生成一段代码,如下: 从这个图片中,可以看到控件的属性都是用的weak,这是为什么呢? 首先,如果把weak修改成strong其实也是可以的,但是会出现一个问 ...

  6. JUC包Lock机制的支持--AQS

    在上一次总结中,提到了JUC包下使用Lock接口实现同步的方法,以及和Synchronized关键字的一些比较,那么使用Lock完成锁机制的底层支持又是什么呢?总结如下: 1 AQS是什么 AQS是一 ...

  7. 同步机制之一--Synchronized,以及此机制下的锁的本质和种类

    Java中,为了实现同步的操作临界区,线程在执行临界区的代码时,需要获得某个对象的锁.本文介绍获得对象的锁的方法之一----Synchronized关键字. Synchronized关键字的用法 Cl ...

  8. 撤销git add添加的文件

    git add 添加了多余文件 git add .  表示当前目录所有文件,不小心就会提交其他文件 git add 如果添加了错误的文件的话 撤销操作 git status 先看一下add 中的文件  ...

  9. HDU-3038How Many Answers Are Wrong权值并查集

    How Many Answers Are Wrong 题意:输入一连串的区间和,问和前面的矛盾个数: 思路:我在做专题,知道是并查集,可是还是不知道怎么做,学了一下权值并查集和大佬的优秀思路,感觉回了 ...

  10. codeforce617E-XOR and Favorite Number莫队+异或前缀和

    传送门:http://codeforces.com/contest/617/problem/E 参考:https://blog.csdn.net/keyboarderqq/article/detail ...