• 【UOJ 29】征兵


    【题目描述】:

    一个国王,他拥有一个国家。最近他因为国库里钱太多了,闲着蛋疼要征集一只部队要保卫国家。他选定了N个女兵和M个男兵,但事实上每征集一个兵他就要花10000RMB,即使国库里钱再多也伤不起啊。他发现,某男兵和某女兵之间有某种关系(往正常方面想,一共R种关系),这种关系可以使KING少花一些钱就可以征集到兵,不过国王也知道,在征兵的时候,每一个兵只能使用一种关系来少花钱。这时国王向你求助,问他最少要花多少的钱。

    【输入描述】:

    第一行:T,一共T组数据。

    接下来T组数据,

    第一行包括N,M,R

    接下来的R行 包括Xi,Yi,Vi 表示如果招了第Xi个女兵,再招第Yi个男兵能省Vi元(同样表示如果招了第Yi个男兵,再招第Xi个女兵能也省Vi元)

    【输出描述】:

    共T行,表示每组数据的最终花费是多少(因为国库里的钱只有2^31-1,所以保证最终花费在maxlongint范围内)

    【样例输入】:

    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

    【样例输出】:

    71071
    54223

    【时间限制、数据范围及描述】:

    时间:1s 空间:128M

    T<=5 ,m,n<=10000,r<=50000,Xi<=m,Yi<=n,Vi<=10000,结果<=2^31-1

    题解:一道最小生成树的题目,一开始总想着最大生成树。最后用m*n去减,

               后来才反应过来,可以以n*m-?作为边的长度就可以了,这样就是最小生成树啦!

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int N=100005;
    struct node{
        int u,v,w;
    }e[N];
    int yaochen,jjj;
    int n,m,x,y,z,fa[N];
    int find(int x){
        if(fa[x]!=x) 
           fa[x]=find(fa[x]);
        return fa[x];
    }
    
    bool cmp(node pp,node qq) 
       {  return pp.w<qq.w;  }
    
    int main(){
       
        scanf("%d",&yaochen);
        while(yaochen--){
            scanf("%d %d %d",&n,&m,&jjj);
            for(int i=1;i<=m+n;i++) fa[i]=i;
            
            for(int i=1;i<=jjj;i++){
                scanf("%d %d %d",&x,&y,&z);
                e[i].u=x+1; e[i].v=y+n+1; e[i].w=10000-z;
            }
            n+=m; int sum=n;
            sort(e+1,e+jjj+1,cmp);
            int ans=0; int tot=0;
            for(int i=1;i<=jjj;i++){
                int uu=find(e[i].u);
                int vv=find(e[i].v);
                if(uu==vv) continue;
                fa[uu]=vv; ans+=e[i].w; tot++; sum--;
                //if(tot==(n-1)) break;
            }
            cout<<ans+sum*10000<<endl;
        }
        return 0;
    }
  • 相关阅读:
    【Linux】命令——基本命令
    正则表达式
    Letex
    Markdown
    文本编辑器Vim
    【Linux】集群
    【Linux】软件安装
    共线性synteny
    windows触控手势
    【Linux】bin结尾的安装包
  • 原文地址:https://www.cnblogs.com/wuhu-JJJ/p/13511508.html
Copyright © 2020-2023  润新知