zoukankan      html  css  js  c++  java
  • 【9018:1458】征兵

    1458: 征兵

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 98  解决: 49
    [提交][状态][讨论版]

    题目描述

    一个国王,他拥有一个国家。最近他因为国库里钱太多了,闲着蛋疼要征集一只部队要保卫国家。他选定了N个女兵(编号0...N-1)和M个男兵(编号0...M-1),但事实上每征集一个兵他就要花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

    提示

    数据范围

    数据保证T<=5 ,m,n<=10000,r<=50000,Xi<=m,Yi<=n,Vi<=10000,结果<=2^31-1
    题解:这题实际上是一个最大生成树,用总花费减去最多节省的钱数即为答案。
    代码如下:
     1 #include<iostream> 
     2 #include<cstring> 
     3 #include<cstdio> 
     4 #include<algorithm> 
     5 using namespace std; 
     6 struct edge{ 
     7     int x,y,val; 
     8 }e[50005]; 
     9 int fa[50005],n,m,r,t; 
    10 bool cmp(edge a,edge b){ 
    11     return a.val>b.val; 
    12 } 
    13 int find(int x){ 
    14     if(fa[x]==x) return x; 
    15     return fa[x]=find(fa[x]); 
    16 } 
    17 void unite(int x,int y){ 
    18     int fx=find(x),fy=find(y); 
    19     if(fx==fy) return; 
    20     fa[fx]=fy; 
    21 } 
    22 int kruskal() 
    23 { 
    24     sort(e,e+r,cmp); 
    25     for(int i=0;i<n+m;i++) fa[i]=i; 
    26     int ans=0; 
    27     for(int i=0;i<r;i++){ 
    28         edge ed=e[i]; 
    29         if(find(ed.x)!=find(ed.y)){ 
    30             unite(ed.x,ed.y); 
    31             ans+=ed.val; 
    32         } 
    33     } 
    34     return ans; 
    35 } 
    36 int main() 
    37 { 
    38     scanf("%d",&t); 
    39     while(t--){ 
    40         scanf("%d%d%d",&n,&m,&r); 
    41         for(int i=0;i<r;i++){ 
    42             scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].val); 
    43             e[i].y+=n; 
    44         } 
    45         printf("%d
    ",10000*(n+m)-kruskal()); 
    46     } 
    47     return 0; 
    48 } 
  • 相关阅读:
    android中statusbar高度的问题
    int和short做循环计数器时的效率问题
    解决Rectangle Packing问题【原创】
    10个android开源项目(转)
    自动编译.9.png文件
    通过wifi调试android程序
    HBase 性能优化笔记
    [转载]定制CentOS 6.3 自动安装盘
    region split时metascan出现regioninfo为空
    Google Dremel 原理 如何能3秒分析1PB
  • 原文地址:https://www.cnblogs.com/Beginner-/p/7471240.html
Copyright © 2011-2022 走看看