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));
        }
    }
    
  • 相关阅读:
    异常类
    设计模式
    java的参数传递
    meta 标签中 http-equiv 的作用
    导入CSV格式文件方法
    第四次博客作业-结对项目
    第九次作业-接口及接口回调
    第八次作业-继承
    软件工程第三次作业——关于软件质量保障初探
    Java第七次作业
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758806.html
Copyright © 2011-2022 走看看