• Poj 3723 Conscription


    http://poj.org/problem?id=3723

    题意:需要招募女兵N人,男兵M人。每征募一人需要$10000。但是如果两个人之间(已征募与要被征募)有关系,就可以依据亲密度大小减免花费,此时花费等于10000-已经征募的人中与ta的最大亲密度。求花费最少的招募顺序。

    题解:是一个无向图,并且可以得知这是一个森林,所以可以把人看做点,关系是边权,就转换为求最大权森林。将边权取反,采用kruskal(因为可能有圈)。

      1 //
      2 //  main.cpp
      3 //  poj 3723
      4 //
      5 //  Created by zhang on 14-3-31.
      6 //  Copyright (c) 2014年 apple. All rights reserved.
      7 //
      8 
      9 #include <iostream>
     10 #include <cstdio>
     11 #include <cmath>
     12 #include <algorithm>
     13 #include <queue>
     14 #include <stack>
     15 #include <cstdlib>
     16 
     17 using namespace std;
     18 
     19 const int maxn=50010;
     20 
     21 int par[maxn];//并查集父亲
     22 int hrank[maxn];//并查集树的高度
     23 int x[maxn],y[maxn],d[maxn];
     24 struct edge{
     25     int u,v,cost;
     26 };
     27 edge es[maxn];
     28 int V,E;
     29 void init(int n)
     30 {
     31     for (int i=0; i<n; i++) {
     32         par[i]=i;
     33         hrank[i]=0;
     34     }
     35 }
     36 
     37 int find(int x)
     38 {
     39     if (par[x]==x) {
     40         return x;
     41     }
     42     else {
     43         return par[x]=find(par[x]);
     44     }
     45 }
     46 
     47 void unite(int x,int y)
     48 {
     49     x=find(x);
     50     y=find(y);
     51     if (x==y) {
     52         return;
     53     }
     54     if (hrank[x]<hrank[y]) {
     55         par[x]=y;
     56     }
     57     else {
     58         par[y]=x;
     59         if (hrank[x]==hrank[y]) {
     60             hrank[x]++;
     61         }
     62     }
     63 }
     64 
     65 bool same(int x,int y)
     66 {
     67     return find(x)==find(y);
     68 }
     69 
     70 bool cmp(const edge& e1,const edge& e2)
     71 {
     72     return e1.cost<e2.cost;
     73 }
     74 
     75 int kruskal()
     76 {
     77     sort(es, es+E, cmp);
     78     init(V);
     79     int res=0;
     80     for (int i=0; i<E; i++) {
     81         edge e=es[i];
     82         if (!same(e.u,e.v)) {
     83             unite(e.u, e.v);
     84             res+=e.cost;
     85         }
     86     }
     87     return res;
     88 }
     89 
     90 int main()
     91 {
     92     //freopen("/Users/apple/Desktop/poj 3723/poj 3723/in", "r", stdin);
     93     //freopen("/Users/apple/Desktop/poj 3723/poj 3723/out", "w", stdout);
     94     int n;
     95     int N,M,R;
     96     scanf("%d",&n);
     97     for (int i=0; i<n; i++) {
     98         scanf("%d%d%d",&N,&M,&R);
     99         V=N+M;
    100         E=R;
    101         for (int j=0; j<R; j++) {
    102             scanf("%d%d%d",&x[j],&y[j],&d[j]);
    103             es[j]=(edge){x[j],N+y[j],-d[j]};//N+y[j]……
    104         }
    105         printf("%d
    ",10000*(N+M)+kruskal());
    106         
    107     }
    108     
    109     return 0;
    110 }
  • 相关阅读:
    Asp.net中导出Excel文档(Gridview)
    以太坊难度炸弹是什么?极大抑制矿工继续以POW方式挖矿!
    Solidity语言基础 和 Etherum ERC20合约基础
    BCH/BSV coin split troubleshooting
    比特币学习-Transaction的locktime属性
    在BCH硬分叉后防止重放攻击-2
    在BCH硬分叉后防止重放攻击-1
    区块链硬分叉-软分叉简单了解
    BTC和BCH 区别和联系?
    BCHABC/BCHSV的矛盾所在
  • 原文地址:https://www.cnblogs.com/der-z/p/3636755.html
Copyright © 2020-2023  润新知