zoukankan      html  css  js  c++  java
  • 洛谷 P2212 [USACO14MAR]浇地Watering the Fields

                     洛谷 P2212 [USACO14MAR]浇地Watering the Fields

    题目描述

    农民约翰想建立一个灌溉系统,给他的NN (1 <= NN <= 2000)块田送水。农田在一个二维平面上,第i块农田坐标为(x_ixi , y_iyi )(0 <= x_ixi , y_iyi <= 1000),在农田ii 和农田jj 自己铺设水管的费用是这两块农田的欧几里得距离的平方(x_i - x_j)^2 + (y_i - y_j)^2(xixj)2+(yiyj)2 。

    农民约翰希望所有的农田之间都能通水,而且希望花费最少的钱。但是安装工人拒绝安装费用小于C的水管(1 <= CC <= 1,000,000)。

    请帮助农民约翰建立一个花费最小的灌溉网络,如果无法建立请输出-1。

    输入输出格式

    输入格式:

    * Line 1: The integers N and C.

    * Lines 2..1+N: Line i+1 contains the integers xi and yi.

    输出格式:

    * Line 1: The minimum cost of a network of pipes connecting the

    fields, or -1 if no such network can be built.

    输入输出样例

    输入样例#1: 复制
    3 11
    0 2
    5 0
    4 3
    输出样例#1: 复制
    46

    说明

    输入信息:

    在地点(0,2),(5,0)和(4,3)有3个字段。 承包商

    将只安装成本至少为11的管道。

    输出细节:

    自从(4,3)和(5,0)以来,FJ不能在字段之间建立管道

    成本将只有10元。他因此在(0,2)和(5,0)之间建立一条管道,

    成本为29,管道为(0.2)至(4,3),成本为17。

    来源:USACO 2014年3月比赛,银牌

    考察算法:生成树          难度:普及+/提高

    思路:通过每个点的横、纵坐标,求出每两点间的距离    暂且按O(n^2)来算

          判断计算出的距离是否小于题目中的C,然后建边

          然后就是简单地最小生成树啦啦啦

    #include<algorithm>
    #include<cstdio>
    #define N 2005
    using namespace std;
    int n, m, tot, sum;
    int fa[N];
    int xx[N], yy[N];
    struct nond {
        int l, r;
        int s;
    }e[N*(N-1)];    //注意数组不要开得太小,会RE的(比如我)qwq 
    
    int find(int x) {
        if(fa[x]==x) return x;
        else return fa[x] = find(fa[x]);
    }
    
    bool cmp(nond x, nond y) {
        return x.s < y.s;
    }
    
    int main() {
        int k = 0;
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++) fa[i] = i;
        for(int i = 1; i <= n; i++) scanf("%d%d", &xx[i], &yy[i]);
        for(int i = 1; i <= n; i++)
            for(int j = i+1; j <= n; j++) {
                int tmp = (xx[i]-xx[j])*(xx[i]-xx[j]) + (yy[i]-yy[j])*(yy[i]-yy[j]);    //求出每两点间的距离 
                if(tmp >= m) e[++k].l = i, e[k].r = j, e[k].s = tmp;    //判断是否建边 
            }
        sort(e+1, e+k+1, cmp);
        for(int i = 1; i <= k; i++) {
            int x = find(e[i].l), y = find(e[i].r);
            if(x == y) continue;
            fa[x] = y;
            tot++;
            sum += e[i].s;
            if(tot == n-1) break;    //小小的优化 
        }
        if(tot < n-1) printf("-1");    //注意不要漏了输出 -1 
        else printf("%d", sum);
        return 0;
    }
  • 相关阅读:
    js 百度地图和谷歌地图的选择
    angular4 自定义表单验证Validator
    推荐20个很有帮助的 Web 前端开发教程
    前端同学大福利,最全的面试题目整理
    前端开发:如何写一手漂亮的 Vue
    推荐20个很有帮助的 Web 前端开发教程
    面试分享:一年经验初探阿里巴巴前端社招
    想成为一个高效的Web开发者吗?来看看大牛分享的经验吧~ #精选JAVASCRIPT前端开发
    初学者Web介绍一些前端开发中的基本概念用到的技术
    Web设计新手应知道的10个锦囊妙计
  • 原文地址:https://www.cnblogs.com/v-vip/p/8591456.html
Copyright © 2011-2022 走看看