zoukankan      html  css  js  c++  java
  • 【最大生成树】Conscription

    Conscription
    Time Limit: 1000MS   Memory Limit: 65536K
         

    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, N, M and R.
    Then R lines followed, each contains three integers xi, yi and di.
    There is a blank line before each test case.

    1 ≤ N, M ≤ 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
    

    OJ:POJ

    题目大意

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

    分析

    征募人的时候尽可能找亲密度大的,即最大生成树问题,用征募N+M人的费用减去最大生成树的总权值即所需最小费用。

    参考代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    struct Edge{
    int x;
    int y;
    int weight;
    }edge[50001];
    int par[20001];
    int rank[20001];
    int vertex_num,arc_num,case_num;
    int N,M,R;
    int ans,sum;
    
    void init();
    int find(int x);
    bool unite(int x,int y);
    bool compare(const Edge &a,const Edge &b);
    void kruskal();
    
    int main()
    {
        scanf("%d",&case_num);
        while(case_num){
            sum=0;
            scanf("%d%d%d",&N,&M,&R);
            vertex_num=N+M;
            arc_num=R;
            for(int i=0;i<R;i++){
                scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].weight);
                edge[i].y+=N;//区别男女兵
            }
            kruskal();
            int ans=10000*vertex_num-sum;
            printf("%d
    ",ans);
            case_num--;
        }
    
        return 0;
    }
    
    void init(){
        for(int i=0;i<vertex_num;i++){
            par[i]=i;
            rank[i]=0;
        }
    
    }
    
    int find(int x){
    if(x==par[x])
        return x;
    else{
        return par[x]=find(par[x]);
    }
    }
    
    bool unite(int x,int y){
    int r1=find(x);
    int r2=find(y);
    if(r1==r2)
        return false;
    else{
        if(rank[r1]>rank[r2]){
            par[r2]=r1;
        }
        else if(rank[r1]<rank[r2]){
            par[r1]=r2;
        }
        else{
            par[r2]=r1;
            rank[r1]++;
        }
        return true;
    
        }
    }
    
    bool compare(const Edge &a,const Edge &b){
        return a.weight>b.weight;
    }
    
    void kruskal(){
        init();
        sort(edge,edge+arc_num,compare);
        for(int i=0;i<arc_num;i++){
            if(unite(edge[i].x,edge[i].y)){
                sum+=edge[i].weight;
            }
        }
    }

     

     

     

     

  • 相关阅读:
    iOS9请求https问题-记录
    邓白氏码的申请-iOS公司开发者账号准备
    iOS学习笔记---oc语言第八天
    iOS学习笔记---oc语言第七天
    iOS学习笔记---oc语言第六天
    一道例题的详解
    使用使用for in 语句,并对数组中元素进行了增删操作,报错却不知怎么办?
    iOS学习笔记---oc语言第五天
    iOS学习笔记---oc语言第四天
    Xcode编译异常和警告汇总(持续更新中)
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7424194.html
Copyright © 2011-2022 走看看