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

 

posted @ 2018-03-17 17:40  落云小师妹  阅读(212)  评论(0编辑  收藏  举报