zoukankan      html  css  js  c++  java
  • POJ 3723 Conscription【最小生成树】

    题意:

    征用一些男生和女生,每个应都要给10000元,但是如果某个男生和女生之间有关系,则给的钱数为10000减去相应的亲密度,征集一个士兵时一次关系只能使用一次。

    分析:

    kruskal求最小生成树,注意男生和女生用偏移量处理。

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    struct edge{int u, v, w;};
    const int maxn = 20050, maxm = 50005;
    edge e[maxm];
    int n, m ,R;
    int pa[maxn], _rank[maxn];
    bool cmp(const edge &e1,const edge &e2)
    {
        return e1.w<e2.w;
    }
    int _find(int a)
    {
        if(a == pa[a]) return a;
        else return pa[a] = _find(pa[a]);
    }
    void unite(int a, int b)
    {
        int ra = _find(a), rb = _find(b);
        if(_rank[ra] < _rank[b]) pa[ra] = rb;
        else{
            pa[rb] = ra;
            if(_rank[ra] == _rank[rb]) _rank[ra]++;
        }
        return;
    }
    int same(int a, int b)
    {
        return _find(a) == _find(b);
    }
    int kruskal(int r)
    {
        sort(e, e+r, cmp);
        for(int i = 0; i <  n+m; i++){
           pa[i] = i;
        }
        int res = 0;
        for(int i = 0; i < r; i++){
            if(!same(e[i].u,e[i].v)){
                unite(e[i].u, e[i].v);
                res += e[i].w;
            }
        }
        return res;
    }
    int main (void)
    {
        int c;scanf("%d",&c);
        while(c--){
            fill(_rank, _rank + n + m, 1);
            scanf("%d%d%d",&n,&m,&R);
            int x, y, r;
            for(int i = 0; i < R;i++){
                scanf("%d%d%d",&x, &y, &r);
                e[i] = (edge){x, y + n, -r};
          }
          printf("%d
    ",10000*(n+m) + kruskal(R));
        }
    }
    
  • 相关阅读:
    Lua 虚拟机指令
    如何打包和部署air应用程序
    demjson
    mongo批量插入问题(insert_many,bulk_write),spark df转json传入mongo
    python isinstance()方法的使用
    python 时间对应计算
    第三方库-正则re
    第三方库-时间函数dateutil
    Mongodb操作-更新操作符
    python文件操作-1.将PDF转成Excel
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758806.html
Copyright © 2011-2022 走看看