zoukankan      html  css  js  c++  java
  • 【POJ

    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(0); 
        cin.tie(0);
    #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 = 0; 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 = 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;
        scanf("%d", &T);
        while (T--)//T组测试样例
        {
            scanf("%d%d%d", &N, &M, &R);//存数据
            for (int i = 0; i < R; i++)
                scanf("%d%d%d", &x[i], &y[i], &d[i]);
            int V, E;
            V = N + M;//顶点个数
            E = R;//边个数
            for (int i = 0; i < E; i++)//存入结构体
            {
                es[i] = (edge){
                    x[i], N + y[i], -d[i]};
            }
            printf("%d
    ", 10000 * (N + M) + kruskal(V, E));
        }
        return 0;
    }
    #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(0); 
        cin.tie(0);
    #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 &e1const edge &e2)//从小到大排序
    {
        return e1.cost < e2.cost;
    }
    edge es[Maxn];
    int par[Maxn];
    void init(int n)//初始化并查集
    {
        for (int i = 0; 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 xint y)//合并
    {
        x = findr(x);
        y = findr(y);
        if (x == y)
            return;
        par[x] = y;
    }
    bool same(int xint y)//判断根是否相同
    {
        return findr(x) == findr(y);
    }
    int kruskal(int Vint E)//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.ue.v))
            {
                unite(e.ue.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 = 0; i < R; i++)
                scanf("%d%d%d"&x[i], &y[i], &d[i]);
            int V, E;
            V = N + M;//顶点个数
            E = R;//边个数
            for (int i = 0; i < E; i++)//存入结构体
            {
                es[i] = (edge){
                    x[i], N + y[i], -d[i]};
            }
            printf("%d "10000 * (N + M) + kruskal(V, E));
        }
        return 0;
    }
  • 相关阅读:
    hadoop之 distcp(分布式拷贝)
    LINUX下mysql客户端不能输入中文
    logstash-input-jdbc配置说明
    数据收集之binlog同步 Maxwell --->Kafka
    MySQL的binlog日志
    SqlServer字段说明查询及快速查看表结构
    【HTTP】C1-Web及网络基础
    第 2 期:['1', '2', '3'].map(parseInt) what & why
    用表单处理用户输入
    德国Vue.js2终极开发教程033--
  • 原文地址:https://www.cnblogs.com/sky-stars/p/11587399.html
Copyright © 2011-2022 走看看