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;
            }
        }
    }

     

     

     

     

  • 相关阅读:
    51nod 1412 AVL树的种类(经典dp)
    HDU 6141 I am your Father!(最小树形图+权值编码)
    POJ 3164 Command Network(最小树形图模板题+详解)
    HDU 6125 Free from square(状态压缩+分组背包)
    HDU 6143 Killer Names(容斥原理)
    CSU 1808 地铁(最短路变形)
    HDU 6128 Inverse of sum(同余)
    HDU 6121 Build a tree(完全K叉树)
    HDU 6129 Just do it(杨辉三角)
    HDU 6127 Hard challenge(扫描线)
  • 原文地址:https://www.cnblogs.com/LuRenJiang/p/7424194.html
Copyright © 2011-2022 走看看